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 neccessary to have cmd.scan_end_arg=cmd.chanlist_len but
27 cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
28 - If return value of cmdtest is 5 then you've bad channel list
29 (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
32 There are some hardware limitations:
33 a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
35 b) DMA transfers must have the length aligned to two samples (32 bit),
36 so there is some problems if cmd->chanlist_len is odd. This driver tries
37 bypass this with adding one sample to the end of the every scan and discard
38 it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
39 and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
40 with interrupt after every sample.
41 c) If isn't used DMA then you can use only mode where
42 cmd->scan_begin_src=TRIG_FOLLOW.
44 Configuration options:
45 [0] - PCI bus of device (optional)
46 [1] - PCI slot of device (optional)
47 If bus/slot is not specified, then first available PCI
49 [2] - 0= standard 8 DIFF/16 SE channels configuration
50 n = external multiplexer connected, 1 <= n <= 256
51 [3] - 0=autoselect DMA or EOC interrupts operation
53 3 = disable DMA and INT, only insn interface will work
54 [4] - sample&hold signal - card can generate signal for external S&H board
55 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
56 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
57 long delay is requested in ns and sign polarity of the hold
58 (in this case external multiplexor can serve only 128 channels)
59 [5] - 0=stop measure on all hardware errors
60 2 | = ignore ADOR - A/D Overrun status
61 8|=ignore Bover - A/D Burst Mode Overrun status
62 256|=ignore nFull - A/D FIFO Full status
65 #include "../comedidev.h"
66 #include "../pci_ids.h"
68 #include <linux/delay.h>
69 #include <linux/gfp.h>
70 #include <linux/interrupt.h>
72 #include "amcc_s5933.h"
74 #include "comedi_pci.h"
75 #include "comedi_fc.h"
77 /* paranoid checks are broken */
78 #undef PCI9118_PARANOIDCHECK /*
79 * if defined, then is used code which control
80 * correct channel number on every 12 bit sample
83 #undef PCI9118_EXTDEBUG /*
84 * if defined then driver prints
89 #ifdef PCI9118_EXTDEBUG
90 #define DPRINTK(fmt, args...) printk(fmt, ## args)
92 #define DPRINTK(fmt, args...)
95 #define IORANGE_9118 64 /* I hope */
96 #define PCI9118_CHANLEN 255 /*
97 * len of chanlist, some source say 256,
98 * but reality looks like 255 :-(
101 #define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
102 #define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
103 #define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
104 #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
105 #define PCI9118_AD_DATA 0x10 /* R: A/D data */
106 #define PCI9118_DA1 0x10 /* W: D/A registers */
107 #define PCI9118_DA2 0x14
108 #define PCI9118_ADSTAT 0x18 /* R: A/D status register */
109 #define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
110 #define PCI9118_DI 0x1c /* R: digi input register */
111 #define PCI9118_DO 0x1c /* W: digi output register */
112 #define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
113 #define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
114 #define PCI9118_BURST 0x28 /* W: A/D burst number register */
115 #define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
116 #define PCI9118_ADFUNC 0x30 /* W: A/D function register */
117 #define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
118 #define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
119 #define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
121 /* bits from A/D control register (PCI9118_ADCNTRL) */
122 #define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
123 #define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
124 #define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
125 #define AdControl_ExtG 0x10 /*
126 * 1=8254 countrol controlled by TGIN(pin 46),
127 * 0=controlled by SoftG
129 #define AdControl_ExtM 0x08 /*
130 * 1=external hardware trigger (pin 44),
133 #define AdControl_TmrTr 0x04 /*
134 * 1=8254 is iternal trigger source,
135 * 0=software trigger is source
136 * (register PCI9118_SOFTTRG)
138 #define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
139 #define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
141 /* bits from A/D function register (PCI9118_ADFUNC) */
142 #define AdFunction_PDTrg 0x80 /*
144 * 0=negative digital trigger
145 * (only positive is correct)
147 #define AdFunction_PETrg 0x40 /*
149 * 0=negative external trigger
150 * (only positive is correct)
152 #define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
153 #define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
154 #define AdFunction_BS 0x08 /*
155 * 1=burst mode start,
158 #define AdFunction_PM 0x04 /*
159 * 1=post trigger mode,
162 #define AdFunction_AM 0x02 /*
163 * 1=about trigger mode,
164 * 0=not about trigger
166 #define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
168 /* bits from A/D status register (PCI9118_ADSTAT) */
169 #define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
170 #define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
171 #define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
172 #define AdStatus_Acmp 0x020 /* */
173 #define AdStatus_DTH 0x010 /* 1=external digital trigger */
174 #define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
175 #define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
176 #define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
177 #define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
179 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
180 /* 1=interrupt occur, enable source, 0=interrupt not occur, disable source */
181 #define Int_Timer 0x08 /* timer interrupt */
182 #define Int_About 0x04 /* about trigger complete */
183 #define Int_Hfull 0x02 /* A/D FIFO hlaf full */
184 #define Int_DTrg 0x01 /* external digital trigger */
186 #define START_AI_EXT 0x01 /* start measure on external trigger */
187 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
188 #define START_AI_INT 0x04 /* start measure on internal trigger */
189 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
191 #define EXTTRG_AI 0 /* ext trg is used by AI */
193 static const struct comedi_lrange range_pci9118dg_hr = { 8, {
205 static const struct comedi_lrange range_pci9118hg = { 8, {
217 #define PCI9118_BIPOLAR_RANGES 4 /*
218 * used for test on mixture
222 static int pci9118_attach(struct comedi_device *dev,
223 struct comedi_devconfig *it);
224 static int pci9118_detach(struct comedi_device *dev);
227 const char *name; /* board name */
228 int vendor_id; /* PCI vendor a device ID of card */
230 int iorange_amcc; /* iorange for own S5933 region */
231 int iorange_9118; /* pass thru card region size */
232 int n_aichan; /* num of A/D chans */
233 int n_aichand; /* num of A/D chans in diff mode */
235 * num of A/D chans with
236 * external multiplexor
238 int n_aichanlist; /* len of chanlist */
239 int n_aochan; /* num of D/A chans */
240 int ai_maxdata; /* resolution of A/D */
241 int ao_maxdata; /* resolution of D/A */
242 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
243 const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
244 unsigned int ai_ns_min; /* max sample speed of card v ns */
245 unsigned int ai_pacer_min; /*
246 * minimal pacer value
247 * (c1*c2 or c1 in burst)
249 int half_fifo_size; /* size of FIFO/2 */
253 static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
255 PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
259 MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
261 static const struct boardtype boardtypes[] = {
262 {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
263 AMCC_OP_REG_SIZE, IORANGE_9118,
264 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
265 &range_pci9118dg_hr, &range_bipolar10,
267 {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
268 AMCC_OP_REG_SIZE, IORANGE_9118,
269 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
270 &range_pci9118hg, &range_bipolar10,
272 {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
273 AMCC_OP_REG_SIZE, IORANGE_9118,
274 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
275 &range_pci9118dg_hr, &range_bipolar10,
279 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
281 static struct comedi_driver driver_pci9118 = {
282 .driver_name = "adl_pci9118",
283 .module = THIS_MODULE,
284 .attach = pci9118_attach,
285 .detach = pci9118_detach,
286 .num_names = n_boardtypes,
287 .board_name = &boardtypes[0].name,
288 .offset = sizeof(struct boardtype),
291 COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
293 struct pci9118_private {
294 unsigned long iobase_a; /* base+size for AMCC chip */
295 unsigned int master; /* master capable */
296 struct pci_dev *pcidev; /* ptr to actual pcidev */
297 unsigned int usemux; /* we want to use external multiplexor! */
298 #ifdef PCI9118_PARANOIDCHECK
299 unsigned short chanlist[PCI9118_CHANLEN + 1]; /*
303 unsigned char chanlistlen; /* number of scanlist */
305 unsigned char AdControlReg; /* A/D control register */
306 unsigned char IntControlReg; /* Interrupt control register */
307 unsigned char AdFunctionReg; /* A/D function register */
308 char valid; /* driver is ok */
309 char ai_neverending; /* we do unlimited AI */
310 unsigned int i8254_osc_base; /* frequence of onboard oscilator */
311 unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
312 unsigned int ai_act_scan; /* how many scans we finished */
313 unsigned int ai_buf_ptr; /* data buffer ptr in samples */
314 unsigned int ai_n_chan; /* how many channels is measured */
315 unsigned int ai_n_scanlen; /* len of actual scanlist */
316 unsigned int ai_n_realscanlen; /*
317 * what we must transfer for one
318 * outgoing scan include front/back adds
320 unsigned int ai_act_dmapos; /* position in actual real stream */
321 unsigned int ai_add_front; /*
322 * how many channels we must add
323 * before scan to satisfy S&H?
325 unsigned int ai_add_back; /*
326 * how many channels we must add
327 * before scan to satisfy DMA?
329 unsigned int *ai_chanlist; /* actual chanlist */
330 unsigned int ai_timer1;
331 unsigned int ai_timer2;
332 unsigned int ai_flags;
333 char ai12_startstop; /*
334 * measure can start/stop
335 * on external trigger
337 unsigned int ai_divisor1, ai_divisor2; /*
338 * divisors for start of measure
341 unsigned int ai_data_len;
343 short ao_data[2]; /* data output buffer */
344 unsigned int ai_scans; /* number of scans to do */
345 char dma_doublebuf; /* we can use double buffring */
346 unsigned int dma_actbuf; /* which buffer is used now */
347 short *dmabuf_virt[2]; /*
348 * pointers to begin of
351 unsigned long dmabuf_hw[2]; /* hw address of DMA buff */
352 unsigned int dmabuf_size[2]; /*
353 * size of dma buffer in bytes
355 unsigned int dmabuf_use_size[2]; /*
356 * which size we may now use
359 unsigned int dmabuf_used_size[2]; /* which size was truly used */
360 unsigned int dmabuf_panic_size[2];
361 unsigned int dmabuf_samples[2]; /* size in samples */
362 int dmabuf_pages[2]; /* number of pages in buffer */
363 unsigned char cnt0_users; /*
364 * bit field of 8254 CNT0 users
365 * (0-unused, 1-AO, 2-DI, 3-DO)
367 unsigned char exttrg_users; /*
368 * bit field of external trigger
369 * users(0-AI, 1-AO, 2-DI, 3-DO)
371 unsigned int cnt0_divisor; /* actual CNT0 divisor */
372 void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *,
376 * ptr to actual interrupt
379 unsigned char ai16bits; /* =1 16 bit card */
380 unsigned char usedma; /* =1 use DMA transfer and not INT */
381 unsigned char useeoshandle; /*
382 * =1 change WAKE_EOS DMA transfer
383 * to fit on every second
385 unsigned char usessh; /* =1 turn on S&H support */
387 * >0 use software S&H,
388 * numer is requested delay in ns
390 unsigned char softsshsample; /*
391 * polarity of S&H signal
394 unsigned char softsshhold; /*
395 * polarity of S&H signal
398 unsigned int ai_maskerr; /* which warning was printed */
399 unsigned int ai_maskharderr; /* on which error bits stops */
400 unsigned int ai_inttrig_start; /* TRIG_INT for start */
403 #define devpriv ((struct pci9118_private *)dev->private)
404 #define this_board ((struct boardtype *)dev->board_ptr)
407 ==============================================================================
410 static int check_channel_list(struct comedi_device *dev,
411 struct comedi_subdevice *s, int n_chan,
412 unsigned int *chanlist, int frontadd,
414 static int setup_channel_list(struct comedi_device *dev,
415 struct comedi_subdevice *s, int n_chan,
416 unsigned int *chanlist, int rot, int frontadd,
417 int backadd, int usedma, char eoshandle);
418 static void start_pacer(struct comedi_device *dev, int mode,
419 unsigned int divisor1, unsigned int divisor2);
420 static int pci9118_reset(struct comedi_device *dev);
421 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source);
422 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source);
423 static int pci9118_ai_cancel(struct comedi_device *dev,
424 struct comedi_subdevice *s);
425 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
426 struct comedi_subdevice *s,
427 unsigned int *tim1, unsigned int *tim2,
428 unsigned int flags, int chans,
429 unsigned int *div1, unsigned int *div2,
430 char usessh, unsigned int chnsshfront);
433 ==============================================================================
435 static int pci9118_insn_read_ai(struct comedi_device *dev,
436 struct comedi_subdevice *s,
437 struct comedi_insn *insn, unsigned int *data)
442 devpriv->AdControlReg = AdControl_Int & 0xff;
443 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
444 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
446 * positive triggers, no S&H,
447 * no burst, burst stop,
453 if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
456 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
458 for (n = 0; n < insn->n; n++) {
459 outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
463 if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
468 comedi_error(dev, "A/D insn timeout");
470 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
474 if (devpriv->ai16bits) {
477 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
480 (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
484 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
490 ==============================================================================
492 static int pci9118_insn_write_ao(struct comedi_device *dev,
493 struct comedi_subdevice *s,
494 struct comedi_insn *insn, unsigned int *data)
498 ch = CR_CHAN(insn->chanspec);
500 chanreg = PCI9118_DA2;
502 chanreg = PCI9118_DA1;
505 for (n = 0; n < insn->n; n++) {
506 outl(data[n], dev->iobase + chanreg);
507 devpriv->ao_data[ch] = data[n];
514 ==============================================================================
516 static int pci9118_insn_read_ao(struct comedi_device *dev,
517 struct comedi_subdevice *s,
518 struct comedi_insn *insn, unsigned int *data)
522 chan = CR_CHAN(insn->chanspec);
523 for (n = 0; n < insn->n; n++)
524 data[n] = devpriv->ao_data[chan];
530 ==============================================================================
532 static int pci9118_insn_bits_di(struct comedi_device *dev,
533 struct comedi_subdevice *s,
534 struct comedi_insn *insn, unsigned int *data)
536 data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
542 ==============================================================================
544 static int pci9118_insn_bits_do(struct comedi_device *dev,
545 struct comedi_subdevice *s,
546 struct comedi_insn *insn, unsigned int *data)
549 s->state &= ~data[0];
550 s->state |= (data[0] & data[1]);
551 outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
559 ==============================================================================
561 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
563 devpriv->AdFunctionReg =
564 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
565 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
566 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
567 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
568 dev->iobase + PCI9118_CNT0);
569 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
570 dev->iobase + PCI9118_CNT0);
571 devpriv->AdFunctionReg |= AdFunction_Start;
572 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
575 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
576 struct comedi_subdevice *s,
578 unsigned int num_samples)
580 unsigned int i = 0, j = 0;
581 unsigned int start_pos = devpriv->ai_add_front,
582 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
583 unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
584 devpriv->ai_add_back;
586 for (i = 0; i < num_samples; i++) {
587 if (devpriv->ai_act_dmapos >= start_pos &&
588 devpriv->ai_act_dmapos < stop_pos) {
589 dma_buffer[j++] = dma_buffer[i];
591 devpriv->ai_act_dmapos++;
592 devpriv->ai_act_dmapos %= raw_scanlen;
599 ==============================================================================
601 static unsigned int move_block_from_dma(struct comedi_device *dev,
602 struct comedi_subdevice *s,
604 unsigned int num_samples)
606 unsigned int num_bytes;
608 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
609 devpriv->ai_act_scan +=
610 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
611 s->async->cur_chan += num_samples;
612 s->async->cur_chan %= devpriv->ai_n_scanlen;
614 cfc_write_array_to_buffer(s, dma_buffer,
615 num_samples * sizeof(short));
616 if (num_bytes < num_samples * sizeof(short))
622 ==============================================================================
624 static char pci9118_decode_error_status(struct comedi_device *dev,
625 struct comedi_subdevice *s,
629 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
630 devpriv->ai_maskerr &= ~0x100L;
634 "A/D Burst Mode Overrun Status (Fatal Error!)");
635 devpriv->ai_maskerr &= ~0x008L;
638 comedi_error(dev, "A/D Over Speed Status (Warning!)");
639 devpriv->ai_maskerr &= ~0x004L;
642 comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
643 devpriv->ai_maskerr &= ~0x002L;
645 if (m & devpriv->ai_maskharderr) {
646 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
647 pci9118_ai_cancel(dev, s);
648 comedi_event(dev, s);
655 static void pci9118_ai_munge(struct comedi_device *dev,
656 struct comedi_subdevice *s, void *data,
657 unsigned int num_bytes,
658 unsigned int start_chan_index)
660 unsigned int i, num_samples = num_bytes / sizeof(short);
663 for (i = 0; i < num_samples; i++) {
665 array[i] = be16_to_cpu(array[i]);
666 if (devpriv->ai16bits)
669 array[i] = (array[i] >> 4) & 0x0fff;
675 ==============================================================================
677 static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
678 struct comedi_subdevice *s,
679 unsigned short int_adstat,
680 unsigned int int_amcc,
681 unsigned short int_daq)
683 register short sampl;
685 s->async->events = 0;
687 if (int_adstat & devpriv->ai_maskerr)
688 if (pci9118_decode_error_status(dev, s, int_adstat))
691 sampl = inw(dev->iobase + PCI9118_AD_DATA);
693 #ifdef PCI9118_PARANOIDCHECK
694 if (devpriv->ai16bits == 0) {
695 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
698 ("comedi: A/D SAMPL - data dropout: "
699 "received channel %d, expected %d!\n",
701 devpriv->chanlist[s->async->cur_chan]);
702 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
703 pci9118_ai_cancel(dev, s);
704 comedi_event(dev, s);
709 cfc_write_to_buffer(s, sampl);
710 s->async->cur_chan++;
711 if (s->async->cur_chan >= devpriv->ai_n_scanlen) {
713 s->async->cur_chan %= devpriv->ai_n_scanlen;
714 devpriv->ai_act_scan++;
715 if (!(devpriv->ai_neverending))
716 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
717 /* all data sampled */
718 pci9118_ai_cancel(dev, s);
719 s->async->events |= COMEDI_CB_EOA;
723 if (s->async->events)
724 comedi_event(dev, s);
728 ==============================================================================
730 static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
731 struct comedi_subdevice *s,
732 unsigned short int_adstat,
733 unsigned int int_amcc,
734 unsigned short int_daq)
736 unsigned int next_dma_buf, samplesinbuf, sampls, m;
738 if (int_amcc & MASTER_ABORT_INT) {
739 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
740 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
741 pci9118_ai_cancel(dev, s);
742 comedi_event(dev, s);
746 if (int_amcc & TARGET_ABORT_INT) {
747 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
748 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
749 pci9118_ai_cancel(dev, s);
750 comedi_event(dev, s);
753 if (int_adstat & devpriv->ai_maskerr)
754 /* if (int_adstat & 0x106) */
755 if (pci9118_decode_error_status(dev, s, int_adstat))
758 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;
759 /* number of received real samples */
760 /* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */
762 if (devpriv->dma_doublebuf) { /*
763 * switch DMA buffers if is used
766 next_dma_buf = 1 - devpriv->dma_actbuf;
767 outl(devpriv->dmabuf_hw[next_dma_buf],
768 devpriv->iobase_a + AMCC_OP_REG_MWAR);
769 outl(devpriv->dmabuf_use_size[next_dma_buf],
770 devpriv->iobase_a + AMCC_OP_REG_MWTC);
771 devpriv->dmabuf_used_size[next_dma_buf] =
772 devpriv->dmabuf_use_size[next_dma_buf];
773 if (devpriv->ai_do == 4)
774 interrupt_pci9118_ai_mode4_switch(dev);
778 m = devpriv->ai_data_len >> 1; /*
779 * how many samples is to
783 * DPRINTK("samps=%d m=%d %d %d\n",
784 * samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);
787 move_block_from_dma(dev, s,
788 devpriv->dmabuf_virt[devpriv->dma_actbuf],
790 m = m - sampls; /* m= how many samples was transfered */
792 /* DPRINTK("YYY\n"); */
794 if (!devpriv->ai_neverending)
795 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
796 /* all data sampled */
797 pci9118_ai_cancel(dev, s);
798 s->async->events |= COMEDI_CB_EOA;
801 if (devpriv->dma_doublebuf) { /* switch dma buffers */
802 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
803 } else { /* restart DMA if is not used double buffering */
804 outl(devpriv->dmabuf_hw[0],
805 devpriv->iobase_a + AMCC_OP_REG_MWAR);
806 outl(devpriv->dmabuf_use_size[0],
807 devpriv->iobase_a + AMCC_OP_REG_MWTC);
808 if (devpriv->ai_do == 4)
809 interrupt_pci9118_ai_mode4_switch(dev);
812 comedi_event(dev, s);
816 ==============================================================================
818 static irqreturn_t interrupt_pci9118(int irq, void *d)
820 struct comedi_device *dev = d;
821 unsigned int int_daq = 0, int_amcc, int_adstat;
824 return IRQ_NONE; /* not fully initialized */
826 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;
827 /* get IRQ reasons from card */
828 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
829 /* get INT register from AMCC chip */
832 * DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x
833 * MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n",
834 * int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR),
835 * inl(devpriv->iobase_a+AMCC_OP_REG_MWTC),
836 * inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do);
839 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
840 return IRQ_NONE; /* interrupt from other source */
842 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
843 /* shutdown IRQ reasons in AMCC */
845 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;
846 /* get STATUS register */
848 if (devpriv->ai_do) {
849 if (devpriv->ai12_startstop)
850 if ((int_adstat & AdStatus_DTH) &&
851 (int_daq & Int_DTrg)) {
852 /* start stop of measure */
853 if (devpriv->ai12_startstop & START_AI_EXT) {
854 devpriv->ai12_startstop &=
856 if (!(devpriv->ai12_startstop &
860 /* deactivate EXT trigger */
861 start_pacer(dev, devpriv->ai_do,
862 devpriv->ai_divisor1,
863 devpriv->ai_divisor2);
865 outl(devpriv->AdControlReg,
866 dev->iobase + PCI9118_ADCNTRL);
868 if (devpriv->ai12_startstop &
870 devpriv->ai12_startstop &=
874 /* deactivate EXT trigger */
875 devpriv->ai_neverending = 0;
877 * well, on next interrupt from
878 * DMA/EOC measure will stop
884 (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
892 ==============================================================================
894 static int pci9118_ai_inttrig(struct comedi_device *dev,
895 struct comedi_subdevice *s, unsigned int trignum)
897 if (trignum != devpriv->ai_inttrig_start)
900 devpriv->ai12_startstop &= ~START_AI_INT;
901 s->async->inttrig = NULL;
903 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
904 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
905 if (devpriv->ai_do != 3) {
906 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
907 devpriv->ai_divisor2);
908 devpriv->AdControlReg |= AdControl_SoftG;
910 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
916 ==============================================================================
918 static int pci9118_ai_cmdtest(struct comedi_device *dev,
919 struct comedi_subdevice *s,
920 struct comedi_cmd *cmd)
923 int tmp, divisor1 = 0, divisor2 = 0;
925 /* step 1: make sure trigger sources are trivially valid */
927 tmp = cmd->start_src;
928 cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
929 if (!cmd->start_src || tmp != cmd->start_src)
932 tmp = cmd->scan_begin_src;
934 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
936 cmd->scan_begin_src &= TRIG_FOLLOW;
938 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
941 tmp = cmd->convert_src;
943 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
945 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
947 if (!cmd->convert_src || tmp != cmd->convert_src)
950 tmp = cmd->scan_end_src;
951 cmd->scan_end_src &= TRIG_COUNT;
952 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
956 cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
957 if (!cmd->stop_src || tmp != cmd->stop_src)
965 * make sure trigger sources are
966 * unique and mutually compatible
969 if (cmd->start_src != TRIG_NOW &&
970 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
971 cmd->start_src = TRIG_NOW;
975 if (cmd->scan_begin_src != TRIG_TIMER &&
976 cmd->scan_begin_src != TRIG_EXT &&
977 cmd->scan_begin_src != TRIG_INT &&
978 cmd->scan_begin_src != TRIG_FOLLOW) {
979 cmd->scan_begin_src = TRIG_FOLLOW;
983 if (cmd->convert_src != TRIG_TIMER &&
984 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
985 cmd->convert_src = TRIG_TIMER;
989 if (cmd->scan_end_src != TRIG_COUNT) {
990 cmd->scan_end_src = TRIG_COUNT;
994 if (cmd->stop_src != TRIG_NONE &&
995 cmd->stop_src != TRIG_COUNT &&
996 cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
997 cmd->stop_src = TRIG_COUNT;
1001 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
1002 cmd->start_src = TRIG_NOW;
1006 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
1007 cmd->start_src = TRIG_NOW;
1011 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1012 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
1013 cmd->convert_src = TRIG_TIMER;
1017 if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1018 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
1019 cmd->convert_src = TRIG_TIMER;
1023 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
1024 cmd->stop_src = TRIG_COUNT;
1031 /* step 3: make sure arguments are trivially compatible */
1033 if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
1034 if (cmd->start_arg != 0) {
1039 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1040 if (cmd->scan_begin_arg != 0) {
1041 cmd->scan_begin_arg = 0;
1045 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1046 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1047 cmd->scan_begin_src = TRIG_FOLLOW;
1048 cmd->convert_arg = cmd->scan_begin_arg;
1049 cmd->scan_begin_arg = 0;
1052 if (cmd->scan_begin_src == TRIG_TIMER)
1053 if (cmd->scan_begin_arg < this_board->ai_ns_min) {
1054 cmd->scan_begin_arg = this_board->ai_ns_min;
1058 if (cmd->scan_begin_src == TRIG_EXT)
1059 if (cmd->scan_begin_arg) {
1060 cmd->scan_begin_arg = 0;
1062 if (cmd->scan_end_arg > 65535) {
1063 cmd->scan_end_arg = 65535;
1068 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
1069 if (cmd->convert_arg < this_board->ai_ns_min) {
1070 cmd->convert_arg = this_board->ai_ns_min;
1074 if (cmd->convert_src == TRIG_EXT)
1075 if (cmd->convert_arg) {
1076 cmd->convert_arg = 0;
1080 if (cmd->stop_src == TRIG_COUNT) {
1081 if (!cmd->stop_arg) {
1085 } else { /* TRIG_NONE */
1086 if (cmd->stop_arg != 0) {
1092 if (!cmd->chanlist_len) {
1093 cmd->chanlist_len = 1;
1097 if (cmd->chanlist_len > this_board->n_aichanlist) {
1098 cmd->chanlist_len = this_board->n_aichanlist;
1102 if (cmd->scan_end_arg < cmd->chanlist_len) {
1103 cmd->scan_end_arg = cmd->chanlist_len;
1107 if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1109 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1116 /* step 4: fix up any arguments */
1118 if (cmd->scan_begin_src == TRIG_TIMER) {
1119 tmp = cmd->scan_begin_arg;
1120 /* printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1121 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1122 &divisor2, &cmd->scan_begin_arg,
1123 cmd->flags & TRIG_ROUND_MASK);
1124 /* printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1125 if (cmd->scan_begin_arg < this_board->ai_ns_min)
1126 cmd->scan_begin_arg = this_board->ai_ns_min;
1127 if (tmp != cmd->scan_begin_arg)
1131 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1132 tmp = cmd->convert_arg;
1133 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1134 &divisor2, &cmd->convert_arg,
1135 cmd->flags & TRIG_ROUND_MASK);
1136 /* printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1137 if (cmd->convert_arg < this_board->ai_ns_min)
1138 cmd->convert_arg = this_board->ai_ns_min;
1139 if (tmp != cmd->convert_arg)
1141 if (cmd->scan_begin_src == TRIG_TIMER
1142 && cmd->convert_src == TRIG_NOW) {
1143 if (cmd->convert_arg == 0) {
1144 if (cmd->scan_begin_arg <
1145 this_board->ai_ns_min *
1146 (cmd->scan_end_arg + 2)) {
1147 cmd->scan_begin_arg =
1148 this_board->ai_ns_min *
1149 (cmd->scan_end_arg + 2);
1150 /* printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1154 if (cmd->scan_begin_arg <
1155 cmd->convert_arg * cmd->chanlist_len) {
1156 cmd->scan_begin_arg =
1159 /* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1170 if (!check_channel_list(dev, s, cmd->chanlist_len,
1171 cmd->chanlist, 0, 0))
1172 return 5; /* incorrect channels list */
1178 ==============================================================================
1180 static int Compute_and_setup_dma(struct comedi_device *dev)
1182 unsigned int dmalen0, dmalen1, i;
1184 DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
1185 dmalen0 = devpriv->dmabuf_size[0];
1186 dmalen1 = devpriv->dmabuf_size[1];
1187 DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
1188 devpriv->ai_data_len);
1189 /* isn't output buff smaller that our DMA buff? */
1190 if (dmalen0 > (devpriv->ai_data_len)) {
1191 dmalen0 = devpriv->ai_data_len & ~3L; /*
1192 * align to 32bit down
1195 if (dmalen1 > (devpriv->ai_data_len)) {
1196 dmalen1 = devpriv->ai_data_len & ~3L; /*
1197 * align to 32bit down
1200 DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1202 /* we want wake up every scan? */
1203 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1204 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1205 /* uff, too short DMA buffer, disable EOS support! */
1206 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1208 ("comedi%d: WAR: DMA0 buf too short, can't "
1209 "support TRIG_WAKE_EOS (%d<%d)\n",
1210 dev->minor, dmalen0,
1211 devpriv->ai_n_realscanlen << 1);
1213 /* short first DMA buffer to one scan */
1214 dmalen0 = devpriv->ai_n_realscanlen << 1;
1216 ("21 dmalen0=%d ai_n_realscanlen=%d "
1217 "useeoshandle=%d\n",
1218 dmalen0, devpriv->ai_n_realscanlen,
1219 devpriv->useeoshandle);
1220 if (devpriv->useeoshandle)
1224 ("comedi%d: ERR: DMA0 buf len bug? "
1226 dev->minor, dmalen0);
1231 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1232 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1233 /* uff, too short DMA buffer, disable EOS support! */
1234 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1236 ("comedi%d: WAR: DMA1 buf too short, "
1237 "can't support TRIG_WAKE_EOS (%d<%d)\n",
1238 dev->minor, dmalen1,
1239 devpriv->ai_n_realscanlen << 1);
1241 /* short second DMA buffer to one scan */
1242 dmalen1 = devpriv->ai_n_realscanlen << 1;
1244 ("22 dmalen1=%d ai_n_realscanlen=%d "
1245 "useeoshandle=%d\n",
1246 dmalen1, devpriv->ai_n_realscanlen,
1247 devpriv->useeoshandle);
1248 if (devpriv->useeoshandle)
1252 ("comedi%d: ERR: DMA1 buf len bug? "
1254 dev->minor, dmalen1);
1260 DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1261 /* transfer without TRIG_WAKE_EOS */
1262 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1263 /* if it's possible then allign DMA buffers to length of scan */
1266 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1267 (devpriv->ai_n_realscanlen << 1);
1270 dmalen0 = i; /* uff. very long scan? */
1273 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1274 (devpriv->ai_n_realscanlen << 1);
1277 dmalen1 = i; /* uff. very long scan? */
1279 * if measure isn't neverending then test, if it fits whole
1280 * into one or two DMA buffers
1282 if (!devpriv->ai_neverending) {
1283 /* fits whole measure into one DMA buffer? */
1285 ((devpriv->ai_n_realscanlen << 1) *
1286 devpriv->ai_scans)) {
1288 ("3.0 ai_n_realscanlen=%d ai_scans=%d \n",
1289 devpriv->ai_n_realscanlen,
1292 (devpriv->ai_n_realscanlen << 1) *
1294 DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0,
1298 * fits whole measure into
1302 ((devpriv->ai_n_realscanlen << 1) *
1303 devpriv->ai_scans - dmalen0))
1305 (devpriv->ai_n_realscanlen << 1) *
1306 devpriv->ai_scans - dmalen0;
1307 DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
1314 DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1316 /* these DMA buffer size will be used */
1317 devpriv->dma_actbuf = 0;
1318 devpriv->dmabuf_use_size[0] = dmalen0;
1319 devpriv->dmabuf_use_size[1] = dmalen1;
1321 DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1323 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1324 devpriv->dmabuf_panic_size[0] =
1325 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1326 1) * devpriv->ai_n_scanlen * sizeof(short);
1327 devpriv->dmabuf_panic_size[1] =
1328 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1329 1) * devpriv->ai_n_scanlen * sizeof(short);
1331 devpriv->dmabuf_panic_size[0] =
1332 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1333 devpriv->dmabuf_panic_size[1] =
1334 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1338 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS),
1339 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
1340 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1341 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1342 /* init DMA transfer */
1343 outl(0x00000000 | AINT_WRITE_COMPL,
1344 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1345 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1347 outl(inl(devpriv->iobase_a +
1348 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1349 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1350 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
1351 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1352 /* allow bus mastering */
1354 DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
1359 ==============================================================================
1361 static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
1362 struct comedi_subdevice *s)
1364 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
1365 dev->minor, devpriv->ai_do);
1366 switch (devpriv->ai_do) {
1368 devpriv->AdControlReg |= AdControl_TmrTr;
1371 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1374 devpriv->AdControlReg |= AdControl_ExtM;
1377 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1381 "pci9118_ai_docmd_sampl() mode number bug!\n");
1385 devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
1386 /* transfer function */
1388 if (devpriv->ai12_startstop)
1389 pci9118_exttrg_add(dev, EXTTRG_AI);
1390 /* activate EXT trigger */
1392 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1393 devpriv->IntControlReg |= Int_Timer;
1395 devpriv->AdControlReg |= AdControl_Int;
1397 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
1398 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1399 /* allow INT in AMCC */
1401 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1402 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1403 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1404 if (devpriv->ai_do != 3) {
1405 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1406 devpriv->ai_divisor2);
1407 devpriv->AdControlReg |= AdControl_SoftG;
1409 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1412 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
1417 ==============================================================================
1419 static int pci9118_ai_docmd_dma(struct comedi_device *dev,
1420 struct comedi_subdevice *s)
1422 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
1423 dev->minor, devpriv->ai_do, devpriv->usedma);
1424 Compute_and_setup_dma(dev);
1426 switch (devpriv->ai_do) {
1428 devpriv->AdControlReg |=
1429 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1432 devpriv->AdControlReg |=
1433 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1434 devpriv->AdFunctionReg =
1435 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1437 if (devpriv->usessh && (!devpriv->softsshdelay))
1438 devpriv->AdFunctionReg |= AdFunction_BSSH;
1439 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1442 devpriv->AdControlReg |=
1443 ((AdControl_ExtM | AdControl_Dma) & 0xff);
1444 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1447 devpriv->AdControlReg |=
1448 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1449 devpriv->AdFunctionReg =
1450 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1451 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1452 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1453 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1454 dev->iobase + PCI9118_CNT0);
1455 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1456 dev->iobase + PCI9118_CNT0);
1457 devpriv->AdFunctionReg |= AdFunction_Start;
1460 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1464 if (devpriv->ai12_startstop) {
1465 pci9118_exttrg_add(dev, EXTTRG_AI);
1466 /* activate EXT trigger */
1469 devpriv->int_ai_func = interrupt_pci9118_ai_dma;
1470 /* transfer function */
1472 outl(0x02000000 | AINT_WRITE_COMPL,
1473 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1475 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1476 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1477 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1478 if (devpriv->ai_do != 3) {
1479 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1480 devpriv->ai_divisor2);
1481 devpriv->AdControlReg |= AdControl_SoftG;
1483 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1486 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
1491 ==============================================================================
1493 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1495 struct comedi_cmd *cmd = &s->async->cmd;
1496 unsigned int addchans = 0;
1499 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
1500 devpriv->ai12_startstop = 0;
1501 devpriv->ai_flags = cmd->flags;
1502 devpriv->ai_n_chan = cmd->chanlist_len;
1503 devpriv->ai_n_scanlen = cmd->scan_end_arg;
1504 devpriv->ai_chanlist = cmd->chanlist;
1505 devpriv->ai_data = s->async->prealloc_buf;
1506 devpriv->ai_data_len = s->async->prealloc_bufsz;
1507 devpriv->ai_timer1 = 0;
1508 devpriv->ai_timer2 = 0;
1509 devpriv->ai_add_front = 0;
1510 devpriv->ai_add_back = 0;
1511 devpriv->ai_maskerr = 0x10e;
1513 /* prepare for start/stop conditions */
1514 if (cmd->start_src == TRIG_EXT)
1515 devpriv->ai12_startstop |= START_AI_EXT;
1516 if (cmd->stop_src == TRIG_EXT) {
1517 devpriv->ai_neverending = 1;
1518 devpriv->ai12_startstop |= STOP_AI_EXT;
1520 if (cmd->start_src == TRIG_INT) {
1521 devpriv->ai12_startstop |= START_AI_INT;
1522 devpriv->ai_inttrig_start = cmd->start_arg;
1523 s->async->inttrig = pci9118_ai_inttrig;
1526 if (cmd->stop_src == TRIG_INT) {
1527 devpriv->ai_neverending = 1;
1528 devpriv->ai12_startstop |= STOP_AI_INT;
1531 if (cmd->stop_src == TRIG_NONE)
1532 devpriv->ai_neverending = 1;
1533 if (cmd->stop_src == TRIG_COUNT) {
1534 devpriv->ai_scans = cmd->stop_arg;
1535 devpriv->ai_neverending = 0;
1537 devpriv->ai_scans = 0;
1540 /* use sample&hold signal? */
1541 if (cmd->convert_src == TRIG_NOW) {
1542 devpriv->usessh = 1;
1545 devpriv->usessh = 0;
1548 DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
1549 devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
1550 devpriv->ai12_startstop);
1553 * use additional sample at end of every scan
1554 * to satisty DMA 32 bit transfer?
1556 devpriv->ai_add_front = 0;
1557 devpriv->ai_add_back = 0;
1558 devpriv->useeoshandle = 0;
1559 if (devpriv->master) {
1560 devpriv->usedma = 1;
1561 if ((cmd->flags & TRIG_WAKE_EOS) &&
1562 (devpriv->ai_n_scanlen == 1)) {
1563 if (cmd->convert_src == TRIG_NOW) {
1564 devpriv->ai_add_back = 1;
1566 if (cmd->convert_src == TRIG_TIMER) {
1567 devpriv->usedma = 0;
1569 * use INT transfer if scanlist
1570 * have only one channel
1574 if ((cmd->flags & TRIG_WAKE_EOS) &&
1575 (devpriv->ai_n_scanlen & 1) &&
1576 (devpriv->ai_n_scanlen > 1)) {
1577 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1579 * vpriv->useeoshandle=1; // change DMA transfer
1580 * block to fit EOS on every second call
1582 devpriv->usedma = 0;
1584 * XXX maybe can be corrected to use 16 bit DMA
1587 * well, we must insert one sample
1588 * to end of EOS to meet 32 bit transfer
1590 devpriv->ai_add_back = 1;
1593 } else { /* interrupt transfer don't need any correction */
1594 devpriv->usedma = 0;
1598 * we need software S&H signal?
1599 * It adds two samples before every scan as minimum
1601 if (devpriv->usessh && devpriv->softsshdelay) {
1602 devpriv->ai_add_front = 2;
1603 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1604 /* move it to front */
1605 devpriv->ai_add_front++;
1606 devpriv->ai_add_back = 0;
1608 if (cmd->convert_arg < this_board->ai_ns_min)
1609 cmd->convert_arg = this_board->ai_ns_min;
1610 addchans = devpriv->softsshdelay / cmd->convert_arg;
1611 if (devpriv->softsshdelay % cmd->convert_arg)
1613 if (addchans > (devpriv->ai_add_front - 1)) {
1614 /* uff, still short */
1615 devpriv->ai_add_front = addchans + 1;
1616 if (devpriv->usedma == 1)
1617 if ((devpriv->ai_add_front +
1618 devpriv->ai_n_chan +
1619 devpriv->ai_add_back) & 1)
1620 devpriv->ai_add_front++;
1621 /* round up to 32 bit */
1624 /* well, we now know what must be all added */
1625 devpriv->ai_n_realscanlen = /*
1626 * what we must take from card in real
1627 * to have ai_n_scanlen on output?
1629 (devpriv->ai_add_front + devpriv->ai_n_chan +
1630 devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1631 devpriv->ai_n_chan);
1633 DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1635 devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1636 devpriv->ai_n_chan, devpriv->ai_add_back,
1637 devpriv->ai_n_scanlen);
1639 /* check and setup channel list */
1640 if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1641 devpriv->ai_chanlist, devpriv->ai_add_front,
1642 devpriv->ai_add_back))
1644 if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1645 devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1646 devpriv->ai_add_back, devpriv->usedma,
1647 devpriv->useeoshandle))
1650 /* compute timers settings */
1652 * simplest way, fr=4Mhz/(tim1*tim2),
1653 * channel manipulation without timers effect
1655 if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1656 (cmd->scan_begin_src == TRIG_EXT) ||
1657 (cmd->scan_begin_src == TRIG_INT)) &&
1658 (cmd->convert_src == TRIG_TIMER)) {
1659 /* both timer is used for one time */
1660 if (cmd->scan_begin_src == TRIG_EXT) {
1665 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1666 &cmd->scan_begin_arg, &cmd->convert_arg,
1668 devpriv->ai_n_realscanlen,
1669 &devpriv->ai_divisor1,
1670 &devpriv->ai_divisor2, devpriv->usessh,
1671 devpriv->ai_add_front);
1672 devpriv->ai_timer2 = cmd->convert_arg;
1675 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1676 ((cmd->convert_src == TRIG_TIMER) ||
1677 (cmd->convert_src == TRIG_NOW))) {
1678 /* double timed action */
1679 if (!devpriv->usedma) {
1681 "cmd->scan_begin_src=TRIG_TIMER works "
1682 "only with bus mastering!");
1687 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1688 &cmd->scan_begin_arg, &cmd->convert_arg,
1690 devpriv->ai_n_realscanlen,
1691 &devpriv->ai_divisor1,
1692 &devpriv->ai_divisor2, devpriv->usessh,
1693 devpriv->ai_add_front);
1694 devpriv->ai_timer1 = cmd->scan_begin_arg;
1695 devpriv->ai_timer2 = cmd->convert_arg;
1698 if ((cmd->scan_begin_src == TRIG_FOLLOW)
1699 && (cmd->convert_src == TRIG_EXT)) {
1703 start_pacer(dev, -1, 0, 0); /* stop pacer */
1705 devpriv->AdControlReg = 0; /*
1706 * bipolar, S.E., use 8254, stop 8354,
1707 * internal trigger, soft trigger,
1710 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1711 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1713 * positive triggers, no S&H, no burst,
1714 * burst stop, no post trigger,
1715 * no about trigger, trigger stop
1717 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1719 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1720 inl(dev->iobase + PCI9118_ADSTAT); /*
1724 inl(dev->iobase + PCI9118_INTSRC);
1726 devpriv->ai_act_scan = 0;
1727 devpriv->ai_act_dmapos = 0;
1728 s->async->cur_chan = 0;
1729 devpriv->ai_buf_ptr = 0;
1731 if (devpriv->usedma)
1732 ret = pci9118_ai_docmd_dma(dev, s);
1734 ret = pci9118_ai_docmd_sampl(dev, s);
1736 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1741 ==============================================================================
1743 static int check_channel_list(struct comedi_device *dev,
1744 struct comedi_subdevice *s, int n_chan,
1745 unsigned int *chanlist, int frontadd, int backadd)
1747 unsigned int i, differencial = 0, bipolar = 0;
1749 /* correct channel and range number check itself comedi/range.c */
1751 comedi_error(dev, "range/channel list is empty!");
1754 if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1756 ("comedi%d: range/channel list is too long for "
1757 "actual configuration (%d>%d)!",
1758 dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
1762 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1763 differencial = 1; /* all input must be diff */
1764 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1765 bipolar = 1; /* all input must be bipolar */
1767 for (i = 1; i < n_chan; i++) { /* check S.E/diff */
1768 if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1771 "Differencial and single ended "
1772 "inputs can't be mixtured!");
1775 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1778 "Bipolar and unipolar ranges "
1779 "can't be mixtured!");
1782 if ((!devpriv->usemux) & (differencial) &
1783 (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
1785 "If AREF_DIFF is used then is "
1786 "available only first 8 channels!");
1795 ==============================================================================
1797 static int setup_channel_list(struct comedi_device *dev,
1798 struct comedi_subdevice *s, int n_chan,
1799 unsigned int *chanlist, int rot, int frontadd,
1800 int backadd, int usedma, char useeos)
1802 unsigned int i, differencial = 0, bipolar = 0;
1803 unsigned int scanquad, gain, ssh = 0x00;
1806 ("adl_pci9118 EDBG: BGN: setup_channel_list"
1807 "(%d,.,%d,.,%d,%d,%d,%d)\n",
1808 dev->minor, n_chan, rot, frontadd, backadd, usedma);
1815 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1816 differencial = 1; /* all input must be diff */
1817 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1818 bipolar = 1; /* all input must be bipolar */
1820 /* All is ok, so we can setup channel/range list */
1823 devpriv->AdControlReg |= AdControl_UniP;
1824 /* set unibipolar */
1826 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
1827 /* enable bipolar */
1831 devpriv->AdControlReg |= AdControl_Diff;
1832 /* enable diff inputs */
1834 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
1835 /* set single ended inputs */
1838 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1841 outl(2, dev->iobase + PCI9118_SCANMOD);
1842 /* gods know why this sequence! */
1843 outl(0, dev->iobase + PCI9118_SCANMOD);
1844 outl(1, dev->iobase + PCI9118_SCANMOD);
1846 #ifdef PCI9118_PARANOIDCHECK
1847 devpriv->chanlistlen = n_chan;
1848 for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1849 devpriv->chanlist[i] = 0x55aa;
1852 if (frontadd) { /* insert channels for S&H */
1853 ssh = devpriv->softsshsample;
1854 DPRINTK("FA: %04x: ", ssh);
1855 for (i = 0; i < frontadd; i++) {
1856 /* store range list to card */
1857 scanquad = CR_CHAN(chanlist[0]);
1858 /* get channel number; */
1859 gain = CR_RANGE(chanlist[0]);
1860 /* get gain number */
1861 scanquad |= ((gain & 0x03) << 8);
1862 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1863 DPRINTK("%02x ", scanquad | ssh);
1864 ssh = devpriv->softsshhold;
1869 DPRINTK("SL: ", ssh);
1870 for (i = 0; i < n_chan; i++) { /* store range list to card */
1871 scanquad = CR_CHAN(chanlist[i]); /* get channel number */
1872 #ifdef PCI9118_PARANOIDCHECK
1873 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1875 gain = CR_RANGE(chanlist[i]); /* get gain number */
1876 scanquad |= ((gain & 0x03) << 8);
1877 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1878 DPRINTK("%02x ", scanquad | ssh);
1882 if (backadd) { /* insert channels for fit onto 32bit DMA */
1883 DPRINTK("BA: %04x: ", ssh);
1884 for (i = 0; i < backadd; i++) { /* store range list to card */
1885 scanquad = CR_CHAN(chanlist[0]);
1886 /* get channel number */
1887 gain = CR_RANGE(chanlist[0]); /* get gain number */
1888 scanquad |= ((gain & 0x03) << 8);
1889 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1890 DPRINTK("%02x ", scanquad | ssh);
1894 #ifdef PCI9118_PARANOIDCHECK
1895 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
1896 /* for 32bit operations */
1898 for (i = 1; i < n_chan; i++) { /* store range list to card */
1899 devpriv->chanlist[(n_chan + i) ^ usedma] =
1900 (CR_CHAN(chanlist[i]) & 0xf) << rot;
1902 devpriv->chanlist[(2 * n_chan) ^ usedma] =
1903 devpriv->chanlist[0 ^ usedma];
1904 /* for 32bit operations */
1909 #ifdef PCI9118_EXTDEBUG
1911 for (i = 0; i <= (useeos * n_chan); i++)
1912 DPRINTK("%04x ", devpriv->chanlist[i]);
1917 outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
1918 /* udelay(100); important delay, or first sample will be crippled */
1920 DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1921 return 1; /* we can serve this with scan logic */
1925 ==============================================================================
1926 calculate 8254 divisors if they are used for dual timing
1928 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1929 struct comedi_subdevice *s,
1930 unsigned int *tim1, unsigned int *tim2,
1931 unsigned int flags, int chans,
1932 unsigned int *div1, unsigned int *div2,
1933 char usessh, unsigned int chnsshfront)
1936 ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors"
1937 "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
1938 mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1942 if (*tim2 < this_board->ai_ns_min)
1943 *tim2 = this_board->ai_ns_min;
1944 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1945 tim2, flags & TRIG_ROUND_NEAREST);
1946 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1947 devpriv->i8254_osc_base, *div1, *div2, *tim1);
1950 if (*tim2 < this_board->ai_ns_min)
1951 *tim2 = this_board->ai_ns_min;
1952 DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1954 *div1 = *tim2 / devpriv->i8254_osc_base;
1955 /* convert timer (burst) */
1956 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1958 if (*div1 < this_board->ai_pacer_min)
1959 *div1 = this_board->ai_pacer_min;
1960 DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1962 *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */
1963 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1965 *div2 = *div2 / *div1; /* major timer is c1*c2 */
1966 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1970 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1973 *tim2 = *div1 * devpriv->i8254_osc_base;
1974 /* real convert timer */
1976 if (usessh & (chnsshfront == 0)) /* use BSSH signal */
1977 if (*div2 < (chans + 2))
1980 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1982 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
1983 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
1984 devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
1987 DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
1992 ==============================================================================
1994 static void start_pacer(struct comedi_device *dev, int mode,
1995 unsigned int divisor1, unsigned int divisor2)
1997 outl(0x74, dev->iobase + PCI9118_CNTCTRL);
1998 outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
1999 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
2002 if ((mode == 1) || (mode == 2) || (mode == 4)) {
2003 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
2004 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
2005 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
2006 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
2011 ==============================================================================
2013 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
2016 return -1; /* incorrect source */
2017 devpriv->exttrg_users |= (1 << source);
2018 devpriv->IntControlReg |= Int_DTrg;
2019 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2020 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2021 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2022 /* allow INT in AMCC */
2027 ==============================================================================
2029 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
2032 return -1; /* incorrect source */
2033 devpriv->exttrg_users &= ~(1 << source);
2034 if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */
2035 devpriv->IntControlReg &= ~Int_DTrg;
2036 if (!devpriv->IntControlReg) /* all IRQ disabled */
2037 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
2039 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2040 /* disable int in AMCC */
2041 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2047 ==============================================================================
2049 static int pci9118_ai_cancel(struct comedi_device *dev,
2050 struct comedi_subdevice *s)
2052 if (devpriv->usedma)
2053 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
2054 (~EN_A2P_TRANSFERS),
2055 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
2056 pci9118_exttrg_del(dev, EXTTRG_AI);
2057 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
2058 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2059 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2061 * positive triggers, no S&H, no burst,
2062 * burst stop, no post trigger,
2063 * no about trigger, trigger stop
2065 devpriv->AdControlReg = 0x00;
2066 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2068 * bipolar, S.E., use 8254, stop 8354,
2069 * internal trigger, soft trigger,
2070 * disable INT and DMA
2072 outl(0, dev->iobase + PCI9118_BURST);
2073 outl(1, dev->iobase + PCI9118_SCANMOD);
2074 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
2075 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
2078 devpriv->usedma = 0;
2080 devpriv->ai_act_scan = 0;
2081 devpriv->ai_act_dmapos = 0;
2082 s->async->cur_chan = 0;
2083 s->async->inttrig = NULL;
2084 devpriv->ai_buf_ptr = 0;
2085 devpriv->ai_neverending = 0;
2086 devpriv->dma_actbuf = 0;
2088 if (!devpriv->IntControlReg)
2089 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2090 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2091 /* allow INT in AMCC */
2097 ==============================================================================
2099 static int pci9118_reset(struct comedi_device *dev)
2101 devpriv->IntControlReg = 0;
2102 devpriv->exttrg_users = 0;
2103 inl(dev->iobase + PCI9118_INTCTRL);
2104 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2105 /* disable interrupts source */
2106 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
2107 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
2108 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
2109 devpriv->AdControlReg = 0;
2110 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2112 * bipolar, S.E., use 8254,
2113 * stop 8354, internal trigger,
2115 * disable INT and DMA
2117 outl(0, dev->iobase + PCI9118_BURST);
2118 outl(1, dev->iobase + PCI9118_SCANMOD);
2119 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
2120 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2121 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2123 * positive triggers, no S&H,
2124 * no burst, burst stop,
2130 devpriv->ao_data[0] = 2047;
2131 devpriv->ao_data[1] = 2047;
2132 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
2133 /* reset A/D outs to 0V */
2134 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
2135 outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */
2137 inl(dev->iobase + PCI9118_AD_DATA);
2138 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
2139 outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */
2140 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */
2141 inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */
2142 devpriv->AdControlReg = 0;
2143 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2145 * bipolar, S.E., use 8254,
2146 * stop 8354, internal trigger,
2148 * disable INT and DMA
2151 devpriv->cnt0_users = 0;
2152 devpriv->exttrg_users = 0;
2158 ==============================================================================
2160 static int pci9118_attach(struct comedi_device *dev,
2161 struct comedi_devconfig *it)
2163 struct comedi_subdevice *s;
2165 unsigned short master;
2167 unsigned long iobase_a, iobase_9;
2168 struct pci_dev *pcidev;
2169 int opt_bus, opt_slot;
2171 unsigned char pci_bus, pci_slot, pci_func;
2174 printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
2176 opt_bus = it->options[0];
2177 opt_slot = it->options[1];
2178 if (it->options[3] & 1) {
2179 master = 0; /* user don't want use bus master */
2184 ret = alloc_private(dev, sizeof(struct pci9118_private));
2186 printk(" - Allocation failed!\n");
2190 /* Look for matching PCI device */
2191 errstr = "not found!";
2193 while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
2194 this_board->device_id,
2196 /* Found matching vendor/device. */
2197 if (opt_bus || opt_slot) {
2198 /* Check bus/slot. */
2199 if (opt_bus != pcidev->bus->number
2200 || opt_slot != PCI_SLOT(pcidev->devfn))
2201 continue; /* no match */
2204 * Look for device that isn't in use.
2205 * Enable PCI device and request regions.
2207 if (comedi_pci_enable(pcidev, "adl_pci9118")) {
2209 "failed to enable PCI device and request regions!";
2216 if (opt_bus || opt_slot) {
2217 printk(KERN_ERR " - Card at b:s %d:%d %s\n",
2218 opt_bus, opt_slot, errstr);
2220 printk(KERN_ERR " - Card %s\n", errstr);
2226 pci_set_master(pcidev);
2229 pci_bus = pcidev->bus->number;
2230 pci_slot = PCI_SLOT(pcidev->devfn);
2231 pci_func = PCI_FUNC(pcidev->devfn);
2233 iobase_a = pci_resource_start(pcidev, 0);
2234 iobase_9 = pci_resource_start(pcidev, 2);
2236 printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus,
2237 pci_slot, pci_func, iobase_9, iobase_a);
2239 dev->iobase = iobase_9;
2240 dev->board_name = this_board->name;
2242 devpriv->pcidev = pcidev;
2243 devpriv->iobase_a = iobase_a;
2247 if (it->options[3] & 2)
2248 irq = 0; /* user don't want use IRQ */
2250 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2251 "ADLink PCI-9118", dev)) {
2252 printk(", unable to allocate IRQ %d, DISABLING IT",
2254 irq = 0; /* Can't use IRQ */
2256 printk(", irq=%u", irq);
2259 printk(", IRQ disabled");
2264 if (master) { /* alloc DMA buffers */
2265 devpriv->dma_doublebuf = 0;
2266 for (i = 0; i < 2; i++) {
2267 for (pages = 4; pages >= 0; pages--) {
2268 devpriv->dmabuf_virt[i] =
2269 (short *)__get_free_pages(GFP_KERNEL,
2271 if (devpriv->dmabuf_virt[i])
2274 if (devpriv->dmabuf_virt[i]) {
2275 devpriv->dmabuf_pages[i] = pages;
2276 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
2277 devpriv->dmabuf_samples[i] =
2278 devpriv->dmabuf_size[i] >> 1;
2279 devpriv->dmabuf_hw[i] =
2280 virt_to_bus((void *)
2281 devpriv->dmabuf_virt[i]);
2284 if (!devpriv->dmabuf_virt[0]) {
2285 printk(", Can't allocate DMA buffer, DMA disabled!");
2289 if (devpriv->dmabuf_virt[1])
2290 devpriv->dma_doublebuf = 1;
2294 devpriv->master = master;
2295 if (devpriv->master)
2296 printk(", bus master");
2298 printk(", no bus master");
2300 devpriv->usemux = 0;
2301 if (it->options[2] > 0) {
2302 devpriv->usemux = it->options[2];
2303 if (devpriv->usemux > 256)
2304 devpriv->usemux = 256; /* max 256 channels! */
2305 if (it->options[4] > 0)
2306 if (devpriv->usemux > 128) {
2307 devpriv->usemux = 128;
2308 /* max 128 channels with softare S&H! */
2310 printk(", ext. mux %d channels", devpriv->usemux);
2313 devpriv->softsshdelay = it->options[4];
2314 if (devpriv->softsshdelay < 0) {
2315 /* select sample&hold signal polarity */
2316 devpriv->softsshdelay = -devpriv->softsshdelay;
2317 devpriv->softsshsample = 0x80;
2318 devpriv->softsshhold = 0x00;
2320 devpriv->softsshsample = 0x00;
2321 devpriv->softsshhold = 0x80;
2326 pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
2327 pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64);
2328 /* Enable parity check for parity error */
2330 ret = alloc_subdevices(dev, 4);
2334 s = dev->subdevices + 0;
2335 dev->read_subdev = s;
2336 s->type = COMEDI_SUBD_AI;
2337 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2338 if (devpriv->usemux)
2339 s->n_chan = devpriv->usemux;
2341 s->n_chan = this_board->n_aichan;
2343 s->maxdata = this_board->ai_maxdata;
2344 s->len_chanlist = this_board->n_aichanlist;
2345 s->range_table = this_board->rangelist_ai;
2346 s->cancel = pci9118_ai_cancel;
2347 s->insn_read = pci9118_insn_read_ai;
2349 s->subdev_flags |= SDF_CMD_READ;
2350 s->do_cmdtest = pci9118_ai_cmdtest;
2351 s->do_cmd = pci9118_ai_cmd;
2352 s->munge = pci9118_ai_munge;
2355 s = dev->subdevices + 1;
2356 s->type = COMEDI_SUBD_AO;
2357 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2358 s->n_chan = this_board->n_aochan;
2359 s->maxdata = this_board->ao_maxdata;
2360 s->len_chanlist = this_board->n_aochan;
2361 s->range_table = this_board->rangelist_ao;
2362 s->insn_write = pci9118_insn_write_ao;
2363 s->insn_read = pci9118_insn_read_ao;
2365 s = dev->subdevices + 2;
2366 s->type = COMEDI_SUBD_DI;
2367 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2370 s->len_chanlist = 4;
2371 s->range_table = &range_digital;
2372 s->io_bits = 0; /* all bits input */
2373 s->insn_bits = pci9118_insn_bits_di;
2375 s = dev->subdevices + 3;
2376 s->type = COMEDI_SUBD_DO;
2377 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2380 s->len_chanlist = 4;
2381 s->range_table = &range_digital;
2382 s->io_bits = 0xf; /* all bits output */
2383 s->insn_bits = pci9118_insn_bits_do;
2386 devpriv->i8254_osc_base = 250; /* 250ns=4MHz */
2387 devpriv->ai_maskharderr = 0x10a;
2388 /* default measure crash condition */
2389 if (it->options[5]) /* disable some requested */
2390 devpriv->ai_maskharderr &= ~it->options[5];
2392 switch (this_board->ai_maxdata) {
2394 devpriv->ai16bits = 1;
2397 devpriv->ai16bits = 0;
2404 ==============================================================================
2406 static int pci9118_detach(struct comedi_device *dev)
2412 free_irq(dev->irq, dev);
2413 if (devpriv->pcidev) {
2415 comedi_pci_disable(devpriv->pcidev);
2417 pci_dev_put(devpriv->pcidev);
2419 if (devpriv->dmabuf_virt[0])
2420 free_pages((unsigned long)devpriv->dmabuf_virt[0],
2421 devpriv->dmabuf_pages[0]);
2422 if (devpriv->dmabuf_virt[1])
2423 free_pages((unsigned long)devpriv->dmabuf_virt[1],
2424 devpriv->dmabuf_pages[1]);
2431 ==============================================================================