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
57 say how 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/interrupt.h>
71 #include "amcc_s5933.h"
73 #include "comedi_pci.h"
74 #include "comedi_fc.h"
76 /* paranoid checks are broken */
77 #undef PCI9118_PARANOIDCHECK /* if defined, then is used code which control correct channel number on every 12 bit sample */
79 #undef PCI9118_EXTDEBUG /* if defined then driver prints a lot of messages */
82 #ifdef PCI9118_EXTDEBUG
83 #define DPRINTK(fmt, args...) printk(fmt, ## args)
85 #define DPRINTK(fmt, args...)
88 #define IORANGE_9118 64 /* I hope */
89 #define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */
91 #define PCI9118_CNT0 0x00 /* R/W: 8254 couter 0 */
92 #define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */
93 #define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */
94 #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
95 #define PCI9118_AD_DATA 0x10 /* R: A/D data */
96 #define PCI9118_DA1 0x10 /* W: D/A registers */
97 #define PCI9118_DA2 0x14
98 #define PCI9118_ADSTAT 0x18 /* R: A/D status register */
99 #define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
100 #define PCI9118_DI 0x1c /* R: digi input register */
101 #define PCI9118_DO 0x1c /* W: digi output register */
102 #define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
103 #define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
104 #define PCI9118_BURST 0x28 /* W: A/D burst number register */
105 #define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
106 #define PCI9118_ADFUNC 0x30 /* W: A/D function register */
107 #define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
108 #define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
109 #define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
111 /* bits from A/D control register (PCI9118_ADCNTRL) */
112 #define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
113 #define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
114 #define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
115 #define AdControl_ExtG 0x10 /* 1=8254 countrol controlled by TGIN(pin 46), 0=controled by SoftG */
116 #define AdControl_ExtM 0x08 /* 1=external hardware trigger (pin 44), 0=internal trigger */
117 #define AdControl_TmrTr 0x04 /* 1=8254 is iternal trigger source, 0=software trigger is source (register PCI9118_SOFTTRG) */
118 #define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
119 #define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
121 /* bits from A/D function register (PCI9118_ADFUNC) */
122 #define AdFunction_PDTrg 0x80 /* 1=positive, 0=negative digital trigger (only positive is correct) */
123 #define AdFunction_PETrg 0x40 /* 1=positive, 0=negative external trigger (only positive is correct) */
124 #define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
125 #define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
126 #define AdFunction_BS 0x08 /* 1=burst mode start, 0=burst mode stop */
127 #define AdFunction_PM 0x04 /* 1=post trigger mode, 0=not post trigger */
128 #define AdFunction_AM 0x02 /* 1=about trigger mode, 0=not about trigger */
129 #define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
131 /* bits from A/D status register (PCI9118_ADSTAT) */
132 #define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
133 #define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
134 #define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
135 #define AdStatus_Acmp 0x020 /* */
136 #define AdStatus_DTH 0x010 /* 1=external digital trigger */
137 #define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
138 #define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
139 #define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
140 #define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
142 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
143 /* 1=interrupt occur, enable source, 0=interrupt not occur, disable source */
144 #define Int_Timer 0x08 /* timer interrupt */
145 #define Int_About 0x04 /* about trigger complete */
146 #define Int_Hfull 0x02 /* A/D FIFO hlaf full */
147 #define Int_DTrg 0x01 /* external digital trigger */
149 #define START_AI_EXT 0x01 /* start measure on external trigger */
150 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
151 #define START_AI_INT 0x04 /* start measure on internal trigger */
152 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
154 #define EXTTRG_AI 0 /* ext trg is used by AI */
156 static const struct comedi_lrange range_pci9118dg_hr = { 8, {
168 static const struct comedi_lrange range_pci9118hg = { 8, {
180 #define PCI9118_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */
182 static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it);
183 static int pci9118_detach(struct comedi_device *dev);
186 const char *name; /* board name */
187 int vendor_id; /* PCI vendor a device ID of card */
189 int iorange_amcc; /* iorange for own S5933 region */
190 int iorange_9118; /* pass thru card region size */
191 int n_aichan; /* num of A/D chans */
192 int n_aichand; /* num of A/D chans in diff mode */
193 int mux_aichan; /* num of A/D chans with external multiplexor */
194 int n_aichanlist; /* len of chanlist */
195 int n_aochan; /* num of D/A chans */
196 int ai_maxdata; /* resolution of A/D */
197 int ao_maxdata; /* resolution of D/A */
198 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
199 const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
200 unsigned int ai_ns_min; /* max sample speed of card v ns */
201 unsigned int ai_pacer_min; /* minimal pacer value (c1*c2 or c1 in burst) */
202 int half_fifo_size; /* size of FIFO/2 */
206 static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
207 {PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
211 MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
213 static const struct boardtype boardtypes[] = {
214 {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
215 AMCC_OP_REG_SIZE, IORANGE_9118,
216 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
217 &range_pci9118dg_hr, &range_bipolar10,
219 {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
220 AMCC_OP_REG_SIZE, IORANGE_9118,
221 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
222 &range_pci9118hg, &range_bipolar10,
224 {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
225 AMCC_OP_REG_SIZE, IORANGE_9118,
226 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
227 &range_pci9118dg_hr, &range_bipolar10,
231 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
233 static struct comedi_driver driver_pci9118 = {
234 .driver_name = "adl_pci9118",
235 .module = THIS_MODULE,
236 .attach = pci9118_attach,
237 .detach = pci9118_detach,
238 .num_names = n_boardtypes,
239 .board_name = &boardtypes[0].name,
240 .offset = sizeof(struct boardtype),
243 COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
245 struct pci9118_private {
246 unsigned long iobase_a; /* base+size for AMCC chip */
247 unsigned int master; /* master capable */
248 struct pci_dev *pcidev; /* ptr to actual pcidev */
249 unsigned int usemux; /* we want to use external multiplexor! */
250 #ifdef PCI9118_PARANOIDCHECK
251 unsigned short chanlist[PCI9118_CHANLEN + 1]; /* list of scaned channel */
252 unsigned char chanlistlen; /* number of scanlist */
254 unsigned char AdControlReg; /* A/D control register */
255 unsigned char IntControlReg; /* Interrupt control register */
256 unsigned char AdFunctionReg; /* A/D function register */
257 char valid; /* driver is ok */
258 char ai_neverending; /* we do unlimited AI */
259 unsigned int i8254_osc_base; /* frequence of onboard oscilator */
260 unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
261 unsigned int ai_act_scan; /* how many scans we finished */
262 unsigned int ai_buf_ptr; /* data buffer ptr in samples */
263 unsigned int ai_n_chan; /* how many channels is measured */
264 unsigned int ai_n_scanlen; /* len of actual scanlist */
265 unsigned int ai_n_realscanlen; /* what we must transfer for one outgoing scan include front/back adds */
266 unsigned int ai_act_dmapos; /* position in actual real stream */
267 unsigned int ai_add_front; /* how many channels we must add before scan to satisfy S&H? */
268 unsigned int ai_add_back; /* how many channels we must add before scan to satisfy DMA? */
269 unsigned int *ai_chanlist; /* actaul chanlist */
270 unsigned int ai_timer1;
271 unsigned int ai_timer2;
272 unsigned int ai_flags;
273 char ai12_startstop; /* measure can start/stop on external trigger */
274 unsigned int ai_divisor1, ai_divisor2; /* divisors for start of measure on external start */
275 unsigned int ai_data_len;
277 short ao_data[2]; /* data output buffer */
278 unsigned int ai_scans; /* number of scans to do */
279 char dma_doublebuf; /* we can use double buffring */
280 unsigned int dma_actbuf; /* which buffer is used now */
281 short *dmabuf_virt[2]; /* pointers to begin of DMA buffer */
282 unsigned long dmabuf_hw[2]; /* hw address of DMA buff */
283 unsigned int dmabuf_size[2]; /* size of dma buffer in bytes */
284 unsigned int dmabuf_use_size[2]; /* which size we may now used for transfer */
285 unsigned int dmabuf_used_size[2]; /* which size was trully used */
286 unsigned int dmabuf_panic_size[2];
287 unsigned int dmabuf_samples[2]; /* size in samples */
288 int dmabuf_pages[2]; /* number of pages in buffer */
289 unsigned char cnt0_users; /* bit field of 8254 CNT0 users (0-unused, 1-AO, 2-DI, 3-DO) */
290 unsigned char exttrg_users; /* bit field of external trigger users (0-AI, 1-AO, 2-DI, 3-DO) */
291 unsigned int cnt0_divisor; /* actual CNT0 divisor */
292 void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, unsigned short, unsigned int, unsigned short); /* ptr to actual interrupt AI function */
293 unsigned char ai16bits; /* =1 16 bit card */
294 unsigned char usedma; /* =1 use DMA transfer and not INT */
295 unsigned char useeoshandle; /* =1 change WAKE_EOS DMA transfer to fit on every second */
296 unsigned char usessh; /* =1 turn on S&H support */
297 int softsshdelay; /* >0 use software S&H, numer is requested delay in ns */
298 unsigned char softsshsample; /* polarity of S&H signal in sample state */
299 unsigned char softsshhold; /* polarity of S&H signal in hold state */
300 unsigned int ai_maskerr; /* which warning was printed */
301 unsigned int ai_maskharderr; /* on which error bits stops */
302 unsigned int ai_inttrig_start; /* TRIG_INT for start */
305 #define devpriv ((struct pci9118_private *)dev->private)
306 #define this_board ((struct boardtype *)dev->board_ptr)
309 ==============================================================================
312 static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
313 int n_chan, unsigned int *chanlist, int frontadd, int backadd);
314 static int setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
315 int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
316 int usedma, char eoshandle);
317 static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
318 unsigned int divisor2);
319 static int pci9118_reset(struct comedi_device *dev);
320 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source);
321 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source);
322 static int pci9118_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
323 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
324 struct comedi_subdevice *s, unsigned int *tim1, unsigned int *tim2,
325 unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
326 char usessh, unsigned int chnsshfront);
329 ==============================================================================
331 static int pci9118_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
332 struct comedi_insn *insn, unsigned int *data)
337 devpriv->AdControlReg = AdControl_Int & 0xff;
338 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
339 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */
341 if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
344 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
346 for (n = 0; n < insn->n; n++) {
347 outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
351 if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
356 comedi_error(dev, "A/D insn timeout");
358 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
362 if (devpriv->ai16bits) {
365 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
369 PCI9118_AD_DATA) >> 4) & 0xfff;
373 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
379 ==============================================================================
381 static int pci9118_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
382 struct comedi_insn *insn, unsigned int *data)
386 ch = CR_CHAN(insn->chanspec);
388 chanreg = PCI9118_DA2;
390 chanreg = PCI9118_DA1;
393 for (n = 0; n < insn->n; n++) {
394 outl(data[n], dev->iobase + chanreg);
395 devpriv->ao_data[ch] = data[n];
402 ==============================================================================
404 static int pci9118_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
405 struct comedi_insn *insn, unsigned int *data)
409 chan = CR_CHAN(insn->chanspec);
410 for (n = 0; n < insn->n; n++)
411 data[n] = devpriv->ao_data[chan];
417 ==============================================================================
419 static int pci9118_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
420 struct comedi_insn *insn, unsigned int *data)
422 data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
428 ==============================================================================
430 static int pci9118_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
431 struct comedi_insn *insn, unsigned int *data)
434 s->state &= ~data[0];
435 s->state |= (data[0] & data[1]);
436 outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
444 ==============================================================================
446 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
448 devpriv->AdFunctionReg =
449 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
450 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
451 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
452 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
453 dev->iobase + PCI9118_CNT0);
454 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
455 dev->iobase + PCI9118_CNT0);
456 devpriv->AdFunctionReg |= AdFunction_Start;
457 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
460 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
461 struct comedi_subdevice *s, short *dma_buffer, unsigned int num_samples)
463 unsigned int i = 0, j = 0;
464 unsigned int start_pos = devpriv->ai_add_front,
465 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
466 unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
467 devpriv->ai_add_back;
469 for (i = 0; i < num_samples; i++) {
470 if (devpriv->ai_act_dmapos >= start_pos &&
471 devpriv->ai_act_dmapos < stop_pos) {
472 dma_buffer[j++] = dma_buffer[i];
474 devpriv->ai_act_dmapos++;
475 devpriv->ai_act_dmapos %= raw_scanlen;
482 ==============================================================================
484 static unsigned int move_block_from_dma(struct comedi_device *dev,
485 struct comedi_subdevice *s, short *dma_buffer, unsigned int num_samples)
487 unsigned int num_bytes;
489 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
490 devpriv->ai_act_scan +=
491 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
492 s->async->cur_chan += num_samples;
493 s->async->cur_chan %= devpriv->ai_n_scanlen;
495 cfc_write_array_to_buffer(s, dma_buffer,
496 num_samples * sizeof(short));
497 if (num_bytes < num_samples * sizeof(short))
503 ==============================================================================
505 static char pci9118_decode_error_status(struct comedi_device *dev,
506 struct comedi_subdevice *s, unsigned char m)
509 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
510 devpriv->ai_maskerr &= ~0x100L;
514 "A/D Burst Mode Overrun Status (Fatal Error!)");
515 devpriv->ai_maskerr &= ~0x008L;
518 comedi_error(dev, "A/D Over Speed Status (Warning!)");
519 devpriv->ai_maskerr &= ~0x004L;
522 comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
523 devpriv->ai_maskerr &= ~0x002L;
525 if (m & devpriv->ai_maskharderr) {
526 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
527 pci9118_ai_cancel(dev, s);
528 comedi_event(dev, s);
535 static void pci9118_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
536 void *data, unsigned int num_bytes, unsigned int start_chan_index)
538 unsigned int i, num_samples = num_bytes / sizeof(short);
541 for (i = 0; i < num_samples; i++) {
543 array[i] = be16_to_cpu(array[i]);
544 if (devpriv->ai16bits) {
547 array[i] = (array[i] >> 4) & 0x0fff;
553 ==============================================================================
555 static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
556 struct comedi_subdevice *s, unsigned short int_adstat, unsigned int int_amcc,
557 unsigned short int_daq)
559 register short sampl;
561 s->async->events = 0;
563 if (int_adstat & devpriv->ai_maskerr)
564 if (pci9118_decode_error_status(dev, s, int_adstat))
567 sampl = inw(dev->iobase + PCI9118_AD_DATA);
569 #ifdef PCI9118_PARANOIDCHECK
570 if (devpriv->ai16bits == 0) {
571 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { /* data dropout! */
573 ("comedi: A/D SAMPL - data dropout: received channel %d, expected %d!\n",
575 devpriv->chanlist[s->async->cur_chan]);
576 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
577 pci9118_ai_cancel(dev, s);
578 comedi_event(dev, s);
583 cfc_write_to_buffer(s, sampl);
584 s->async->cur_chan++;
585 if (s->async->cur_chan >= devpriv->ai_n_scanlen) { /* one scan done */
586 s->async->cur_chan %= devpriv->ai_n_scanlen;
587 devpriv->ai_act_scan++;
588 if (!(devpriv->ai_neverending))
589 if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
590 pci9118_ai_cancel(dev, s);
591 s->async->events |= COMEDI_CB_EOA;
595 if (s->async->events)
596 comedi_event(dev, s);
600 ==============================================================================
602 static void interrupt_pci9118_ai_dma(struct comedi_device *dev, struct comedi_subdevice *s,
603 unsigned short int_adstat, unsigned int int_amcc,
604 unsigned short int_daq)
606 unsigned int next_dma_buf, samplesinbuf, sampls, m;
608 if (int_amcc & MASTER_ABORT_INT) {
609 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
610 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
611 pci9118_ai_cancel(dev, s);
612 comedi_event(dev, s);
616 if (int_amcc & TARGET_ABORT_INT) {
617 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
618 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
619 pci9118_ai_cancel(dev, s);
620 comedi_event(dev, s);
624 if (int_adstat & devpriv->ai_maskerr)
625 /* if (int_adstat & 0x106) */
626 if (pci9118_decode_error_status(dev, s, int_adstat))
629 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; /* number of received real samples */
630 /* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */
632 if (devpriv->dma_doublebuf) { /* switch DMA buffers if is used double buffering */
633 next_dma_buf = 1 - devpriv->dma_actbuf;
634 outl(devpriv->dmabuf_hw[next_dma_buf],
635 devpriv->iobase_a + AMCC_OP_REG_MWAR);
636 outl(devpriv->dmabuf_use_size[next_dma_buf],
637 devpriv->iobase_a + AMCC_OP_REG_MWTC);
638 devpriv->dmabuf_used_size[next_dma_buf] =
639 devpriv->dmabuf_use_size[next_dma_buf];
640 if (devpriv->ai_do == 4)
641 interrupt_pci9118_ai_mode4_switch(dev);
645 m = devpriv->ai_data_len >> 1; /* how many samples is to end of buffer */
646 /* DPRINTK("samps=%d m=%d %d %d\n",samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr); */
648 move_block_from_dma(dev, s,
649 devpriv->dmabuf_virt[devpriv->dma_actbuf],
651 m = m - sampls; /* m= how many samples was transfered */
653 /* DPRINTK("YYY\n"); */
655 if (!devpriv->ai_neverending)
656 if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
657 pci9118_ai_cancel(dev, s);
658 s->async->events |= COMEDI_CB_EOA;
661 if (devpriv->dma_doublebuf) { /* switch dma buffers */
662 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
663 } else { /* restart DMA if is not used double buffering */
664 outl(devpriv->dmabuf_hw[0],
665 devpriv->iobase_a + AMCC_OP_REG_MWAR);
666 outl(devpriv->dmabuf_use_size[0],
667 devpriv->iobase_a + AMCC_OP_REG_MWTC);
668 if (devpriv->ai_do == 4)
669 interrupt_pci9118_ai_mode4_switch(dev);
672 comedi_event(dev, s);
676 ==============================================================================
678 static irqreturn_t interrupt_pci9118(int irq, void *d)
680 struct comedi_device *dev = d;
681 unsigned int int_daq = 0, int_amcc, int_adstat;
684 return IRQ_NONE; /* not fully initialized */
686 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf; /* get IRQ reasons from card */
687 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* get INT register from AMCC chip */
689 /* DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do); */
691 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
692 return IRQ_NONE; /* interrupt from other source */
694 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* shutdown IRQ reasons in AMCC */
696 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; /* get STATUS register */
698 if (devpriv->ai_do) {
699 if (devpriv->ai12_startstop)
700 if ((int_adstat & AdStatus_DTH) && (int_daq & Int_DTrg)) { /* start stop of measure */
701 if (devpriv->ai12_startstop & START_AI_EXT) {
702 devpriv->ai12_startstop &=
704 if (!(devpriv->ai12_startstop &
706 pci9118_exttrg_del(dev, EXTTRG_AI); /* deactivate EXT trigger */
707 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2); /* start pacer */
708 outl(devpriv->AdControlReg,
709 dev->iobase + PCI9118_ADCNTRL);
712 ai12_startstop & STOP_AI_EXT) {
713 devpriv->ai12_startstop &=
715 pci9118_exttrg_del(dev, EXTTRG_AI); /* deactivate EXT trigger */
716 devpriv->ai_neverending = 0; /* well, on next interrupt from DMA/EOC measure will stop */
721 (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
729 ==============================================================================
731 static int pci9118_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
732 unsigned int trignum)
734 if (trignum != devpriv->ai_inttrig_start)
737 devpriv->ai12_startstop &= ~START_AI_INT;
738 s->async->inttrig = NULL;
740 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
741 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
742 if (devpriv->ai_do != 3) {
743 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
744 devpriv->ai_divisor2);
745 devpriv->AdControlReg |= AdControl_SoftG;
747 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
753 ==============================================================================
755 static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
756 struct comedi_cmd *cmd)
759 int tmp, divisor1, divisor2;
761 /* step 1: make sure trigger sources are trivially valid */
763 tmp = cmd->start_src;
764 cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
765 if (!cmd->start_src || tmp != cmd->start_src)
768 tmp = cmd->scan_begin_src;
769 if (devpriv->master) {
770 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
772 cmd->scan_begin_src &= TRIG_FOLLOW;
774 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
777 tmp = cmd->convert_src;
778 if (devpriv->master) {
779 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
781 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
783 if (!cmd->convert_src || tmp != cmd->convert_src)
786 tmp = cmd->scan_end_src;
787 cmd->scan_end_src &= TRIG_COUNT;
788 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
792 cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
793 if (!cmd->stop_src || tmp != cmd->stop_src)
799 /* step 2: make sure trigger sources are unique and mutually compatible */
801 if (cmd->start_src != TRIG_NOW &&
802 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
803 cmd->start_src = TRIG_NOW;
807 if (cmd->scan_begin_src != TRIG_TIMER &&
808 cmd->scan_begin_src != TRIG_EXT &&
809 cmd->scan_begin_src != TRIG_INT &&
810 cmd->scan_begin_src != TRIG_FOLLOW) {
811 cmd->scan_begin_src = TRIG_FOLLOW;
815 if (cmd->convert_src != TRIG_TIMER &&
816 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
817 cmd->convert_src = TRIG_TIMER;
821 if (cmd->scan_end_src != TRIG_COUNT) {
822 cmd->scan_end_src = TRIG_COUNT;
826 if (cmd->stop_src != TRIG_NONE &&
827 cmd->stop_src != TRIG_COUNT &&
828 cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
829 cmd->stop_src = TRIG_COUNT;
833 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
834 cmd->start_src = TRIG_NOW;
838 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
839 cmd->start_src = TRIG_NOW;
843 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
844 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
845 cmd->convert_src = TRIG_TIMER;
849 if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
850 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
851 cmd->convert_src = TRIG_TIMER;
855 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
856 cmd->stop_src = TRIG_COUNT;
863 /* step 3: make sure arguments are trivially compatible */
865 if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
866 if (cmd->start_arg != 0) {
871 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
872 if (cmd->scan_begin_arg != 0) {
873 cmd->scan_begin_arg = 0;
877 if ((cmd->scan_begin_src == TRIG_TIMER) &&
878 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
879 cmd->scan_begin_src = TRIG_FOLLOW;
880 cmd->convert_arg = cmd->scan_begin_arg;
881 cmd->scan_begin_arg = 0;
884 if (cmd->scan_begin_src == TRIG_TIMER)
885 if (cmd->scan_begin_arg < this_board->ai_ns_min) {
886 cmd->scan_begin_arg = this_board->ai_ns_min;
890 if (cmd->scan_begin_src == TRIG_EXT)
891 if (cmd->scan_begin_arg) {
892 cmd->scan_begin_arg = 0;
894 if (cmd->scan_end_arg > 65535) {
895 cmd->scan_end_arg = 65535;
900 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
901 if (cmd->convert_arg < this_board->ai_ns_min) {
902 cmd->convert_arg = this_board->ai_ns_min;
906 if (cmd->convert_src == TRIG_EXT)
907 if (cmd->convert_arg) {
908 cmd->convert_arg = 0;
912 if (cmd->stop_src == TRIG_COUNT) {
913 if (!cmd->stop_arg) {
917 } else { /* TRIG_NONE */
918 if (cmd->stop_arg != 0) {
924 if (!cmd->chanlist_len) {
925 cmd->chanlist_len = 1;
929 if (cmd->chanlist_len > this_board->n_aichanlist) {
930 cmd->chanlist_len = this_board->n_aichanlist;
934 if (cmd->scan_end_arg < cmd->chanlist_len) {
935 cmd->scan_end_arg = cmd->chanlist_len;
939 if ((cmd->scan_end_arg % cmd->chanlist_len)) {
941 cmd->chanlist_len * (cmd->scan_end_arg /
949 /* step 4: fix up any arguments */
951 if (cmd->scan_begin_src == TRIG_TIMER) {
952 tmp = cmd->scan_begin_arg;
953 /* printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
954 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
955 &divisor2, &cmd->scan_begin_arg,
956 cmd->flags & TRIG_ROUND_MASK);
957 /* printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
958 if (cmd->scan_begin_arg < this_board->ai_ns_min)
959 cmd->scan_begin_arg = this_board->ai_ns_min;
960 if (tmp != cmd->scan_begin_arg)
964 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
965 tmp = cmd->convert_arg;
966 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
967 &divisor2, &cmd->convert_arg,
968 cmd->flags & TRIG_ROUND_MASK);
969 /* printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
970 if (cmd->convert_arg < this_board->ai_ns_min)
971 cmd->convert_arg = this_board->ai_ns_min;
972 if (tmp != cmd->convert_arg)
974 if (cmd->scan_begin_src == TRIG_TIMER
975 && cmd->convert_src == TRIG_NOW) {
976 if (cmd->convert_arg == 0) {
977 if (cmd->scan_begin_arg <
978 this_board->ai_ns_min *
979 (cmd->scan_end_arg + 2)) {
980 cmd->scan_begin_arg =
981 this_board->ai_ns_min *
982 (cmd->scan_end_arg + 2);
983 /* printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
987 if (cmd->scan_begin_arg <
988 cmd->convert_arg * cmd->chanlist_len) {
989 cmd->scan_begin_arg =
992 /* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1003 if (!check_channel_list(dev, s, cmd->chanlist_len,
1004 cmd->chanlist, 0, 0))
1005 return 5; /* incorrect channels list */
1011 ==============================================================================
1013 static int Compute_and_setup_dma(struct comedi_device *dev)
1015 unsigned int dmalen0, dmalen1, i;
1017 DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
1018 dmalen0 = devpriv->dmabuf_size[0];
1019 dmalen1 = devpriv->dmabuf_size[1];
1020 DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
1021 devpriv->ai_data_len);
1022 /* isn't output buff smaller that our DMA buff? */
1023 if (dmalen0 > (devpriv->ai_data_len)) {
1024 dmalen0 = devpriv->ai_data_len & ~3L; /* allign to 32bit down */
1026 if (dmalen1 > (devpriv->ai_data_len)) {
1027 dmalen1 = devpriv->ai_data_len & ~3L; /* allign to 32bit down */
1029 DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1031 /* we want wake up every scan? */
1032 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1033 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1034 /* uff, too short DMA buffer, disable EOS support! */
1035 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1037 ("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
1038 dev->minor, dmalen0,
1039 devpriv->ai_n_realscanlen << 1);
1041 /* short first DMA buffer to one scan */
1042 dmalen0 = devpriv->ai_n_realscanlen << 1;
1043 DPRINTK("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen0, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
1044 if (devpriv->useeoshandle)
1048 ("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
1049 dev->minor, dmalen0);
1054 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1055 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1056 /* uff, too short DMA buffer, disable EOS support! */
1057 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1059 ("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
1060 dev->minor, dmalen1,
1061 devpriv->ai_n_realscanlen << 1);
1063 /* short second DMA buffer to one scan */
1064 dmalen1 = devpriv->ai_n_realscanlen << 1;
1065 DPRINTK("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen1, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
1066 if (devpriv->useeoshandle)
1070 ("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
1071 dev->minor, dmalen1);
1077 DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1078 /* transfer without TRIG_WAKE_EOS */
1079 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1080 /* if it's possible then allign DMA buffers to length of scan */
1083 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1084 (devpriv->ai_n_realscanlen << 1);
1087 dmalen0 = i; /* uff. very long scan? */
1090 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1091 (devpriv->ai_n_realscanlen << 1);
1094 dmalen1 = i; /* uff. very long scan? */
1095 /* if measure isn't neverending then test, if it whole fits into one or two DMA buffers */
1096 if (!devpriv->ai_neverending) {
1097 /* fits whole measure into one DMA buffer? */
1099 ((devpriv->ai_n_realscanlen << 1) *
1100 devpriv->ai_scans)) {
1101 DPRINTK("3.0 ai_n_realscanlen=%d ai_scans=%d \n", devpriv->ai_n_realscanlen, devpriv->ai_scans);
1103 (devpriv->ai_n_realscanlen << 1) *
1105 DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0,
1108 } else { /* fits whole measure into two DMA buffer? */
1110 ((devpriv->ai_n_realscanlen << 1) *
1111 devpriv->ai_scans - dmalen0))
1114 ai_n_realscanlen << 1) *
1115 devpriv->ai_scans - dmalen0;
1116 DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
1123 DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1125 /* these DMA buffer size we'll be used */
1126 devpriv->dma_actbuf = 0;
1127 devpriv->dmabuf_use_size[0] = dmalen0;
1128 devpriv->dmabuf_use_size[1] = dmalen1;
1130 DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1132 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1133 devpriv->dmabuf_panic_size[0] =
1134 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1135 1) * devpriv->ai_n_scanlen * sizeof(short);
1136 devpriv->dmabuf_panic_size[1] =
1137 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1138 1) * devpriv->ai_n_scanlen * sizeof(short);
1140 devpriv->dmabuf_panic_size[0] =
1141 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1142 devpriv->dmabuf_panic_size[1] =
1143 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1147 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
1148 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1149 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1150 /* init DMA transfer */
1151 outl(0x00000000 | AINT_WRITE_COMPL,
1152 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1153 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1155 outl(inl(devpriv->iobase_a +
1156 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1157 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1158 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow bus mastering */
1160 DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
1165 ==============================================================================
1167 static int pci9118_ai_docmd_sampl(struct comedi_device *dev, struct comedi_subdevice *s)
1169 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
1170 dev->minor, devpriv->ai_do);
1171 switch (devpriv->ai_do) {
1173 devpriv->AdControlReg |= AdControl_TmrTr;
1176 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1179 devpriv->AdControlReg |= AdControl_ExtM;
1182 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1186 "pci9118_ai_docmd_sampl() mode number bug!\n");
1190 devpriv->int_ai_func = interrupt_pci9118_ai_onesample; /* transfer function */
1192 if (devpriv->ai12_startstop)
1193 pci9118_exttrg_add(dev, EXTTRG_AI); /* activate EXT trigger */
1195 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1196 devpriv->IntControlReg |= Int_Timer;
1198 devpriv->AdControlReg |= AdControl_Int;
1200 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow INT in AMCC */
1202 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1203 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1204 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1205 if (devpriv->ai_do != 3) {
1206 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1207 devpriv->ai_divisor2);
1208 devpriv->AdControlReg |= AdControl_SoftG;
1210 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1213 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
1218 ==============================================================================
1220 static int pci9118_ai_docmd_dma(struct comedi_device *dev, struct comedi_subdevice *s)
1222 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
1223 dev->minor, devpriv->ai_do, devpriv->usedma);
1224 Compute_and_setup_dma(dev);
1226 switch (devpriv->ai_do) {
1228 devpriv->AdControlReg |=
1229 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1232 devpriv->AdControlReg |=
1233 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1234 devpriv->AdFunctionReg =
1235 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1237 if (devpriv->usessh && (!devpriv->softsshdelay))
1238 devpriv->AdFunctionReg |= AdFunction_BSSH;
1239 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1242 devpriv->AdControlReg |=
1243 ((AdControl_ExtM | AdControl_Dma) & 0xff);
1244 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1247 devpriv->AdControlReg |=
1248 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1249 devpriv->AdFunctionReg =
1250 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1251 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1252 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1253 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1254 dev->iobase + PCI9118_CNT0);
1255 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1256 dev->iobase + PCI9118_CNT0);
1257 devpriv->AdFunctionReg |= AdFunction_Start;
1260 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1264 if (devpriv->ai12_startstop) {
1265 pci9118_exttrg_add(dev, EXTTRG_AI); /* activate EXT trigger */
1268 devpriv->int_ai_func = interrupt_pci9118_ai_dma; /* transfer function */
1270 outl(0x02000000 | AINT_WRITE_COMPL,
1271 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1273 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1274 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1275 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1276 if (devpriv->ai_do != 3) {
1277 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1278 devpriv->ai_divisor2);
1279 devpriv->AdControlReg |= AdControl_SoftG;
1281 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1284 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
1289 ==============================================================================
1291 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1293 struct comedi_cmd *cmd = &s->async->cmd;
1294 unsigned int addchans = 0;
1297 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
1298 devpriv->ai12_startstop = 0;
1299 devpriv->ai_flags = cmd->flags;
1300 devpriv->ai_n_chan = cmd->chanlist_len;
1301 devpriv->ai_n_scanlen = cmd->scan_end_arg;
1302 devpriv->ai_chanlist = cmd->chanlist;
1303 devpriv->ai_data = s->async->prealloc_buf;
1304 devpriv->ai_data_len = s->async->prealloc_bufsz;
1305 devpriv->ai_timer1 = 0;
1306 devpriv->ai_timer2 = 0;
1307 devpriv->ai_add_front = 0;
1308 devpriv->ai_add_back = 0;
1309 devpriv->ai_maskerr = 0x10e;
1311 /* prepare for start/stop conditions */
1312 if (cmd->start_src == TRIG_EXT)
1313 devpriv->ai12_startstop |= START_AI_EXT;
1314 if (cmd->stop_src == TRIG_EXT) {
1315 devpriv->ai_neverending = 1;
1316 devpriv->ai12_startstop |= STOP_AI_EXT;
1318 if (cmd->start_src == TRIG_INT) {
1319 devpriv->ai12_startstop |= START_AI_INT;
1320 devpriv->ai_inttrig_start = cmd->start_arg;
1321 s->async->inttrig = pci9118_ai_inttrig;
1324 if (cmd->stop_src == TRIG_INT) {
1325 devpriv->ai_neverending = 1;
1326 devpriv->ai12_startstop |= STOP_AI_INT;
1329 if (cmd->stop_src == TRIG_NONE)
1330 devpriv->ai_neverending = 1;
1331 if (cmd->stop_src == TRIG_COUNT) {
1332 devpriv->ai_scans = cmd->stop_arg;
1333 devpriv->ai_neverending = 0;
1335 devpriv->ai_scans = 0;
1338 /* use sample&hold signal? */
1339 if (cmd->convert_src == TRIG_NOW) {
1340 devpriv->usessh = 1;
1343 devpriv->usessh = 0;
1346 DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
1347 devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
1348 devpriv->ai12_startstop);
1350 /* use additional sample at end of every scan to satisty DMA 32 bit transfer? */
1351 devpriv->ai_add_front = 0;
1352 devpriv->ai_add_back = 0;
1353 devpriv->useeoshandle = 0;
1354 if (devpriv->master) {
1355 devpriv->usedma = 1;
1356 if ((cmd->flags & TRIG_WAKE_EOS) &&
1357 (devpriv->ai_n_scanlen == 1)) {
1358 if (cmd->convert_src == TRIG_NOW) {
1359 devpriv->ai_add_back = 1;
1361 if (cmd->convert_src == TRIG_TIMER) {
1362 devpriv->usedma = 0; /* use INT transfer if scanlist have only one channel */
1365 if ((cmd->flags & TRIG_WAKE_EOS) &&
1366 (devpriv->ai_n_scanlen & 1) &&
1367 (devpriv->ai_n_scanlen > 1)) {
1368 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1369 /* vpriv->useeoshandle=1; // change DMA transfer block to fit EOS on every second call */
1370 devpriv->usedma = 0; /* XXX maybe can be corrected to use 16 bit DMA */
1371 } else { /* well, we must insert one sample to end of EOS to meet 32 bit transfer */
1372 devpriv->ai_add_back = 1;
1375 } else { /* interrupt transfer don't need any correction */
1376 devpriv->usedma = 0;
1379 /* we need software S&H signal? It add two samples before every scan as minimum */
1380 if (devpriv->usessh && devpriv->softsshdelay) {
1381 devpriv->ai_add_front = 2;
1382 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) { /* move it to front */
1383 devpriv->ai_add_front++;
1384 devpriv->ai_add_back = 0;
1386 if (cmd->convert_arg < this_board->ai_ns_min)
1387 cmd->convert_arg = this_board->ai_ns_min;
1388 addchans = devpriv->softsshdelay / cmd->convert_arg;
1389 if (devpriv->softsshdelay % cmd->convert_arg)
1391 if (addchans > (devpriv->ai_add_front - 1)) { /* uff, still short :-( */
1392 devpriv->ai_add_front = addchans + 1;
1393 if (devpriv->usedma == 1)
1394 if ((devpriv->ai_add_front +
1395 devpriv->ai_n_chan +
1396 devpriv->ai_add_back) & 1)
1397 devpriv->ai_add_front++; /* round up to 32 bit */
1399 } /* well, we now know what must be all added */
1401 devpriv->ai_n_realscanlen = /* what we must take from card in real to have ai_n_scanlen on output? */
1402 (devpriv->ai_add_front + devpriv->ai_n_chan +
1403 devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1404 devpriv->ai_n_chan);
1406 DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1408 devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1409 devpriv->ai_n_chan, devpriv->ai_add_back,
1410 devpriv->ai_n_scanlen);
1412 /* check and setup channel list */
1413 if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1414 devpriv->ai_chanlist, devpriv->ai_add_front,
1415 devpriv->ai_add_back))
1417 if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1418 devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1419 devpriv->ai_add_back, devpriv->usedma,
1420 devpriv->useeoshandle))
1423 /* compute timers settings */
1424 /* simplest way, fr=4Mhz/(tim1*tim2), channel manipulation without timers effect */
1425 if (((cmd->scan_begin_src == TRIG_FOLLOW) || (cmd->scan_begin_src == TRIG_EXT) || (cmd->scan_begin_src == TRIG_INT)) && (cmd->convert_src == TRIG_TIMER)) { /* both timer is used for one time */
1426 if (cmd->scan_begin_src == TRIG_EXT) {
1431 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1432 &cmd->scan_begin_arg, &cmd->convert_arg,
1433 devpriv->ai_flags, devpriv->ai_n_realscanlen,
1434 &devpriv->ai_divisor1, &devpriv->ai_divisor2,
1435 devpriv->usessh, devpriv->ai_add_front);
1436 devpriv->ai_timer2 = cmd->convert_arg;
1439 if ((cmd->scan_begin_src == TRIG_TIMER) && ((cmd->convert_src == TRIG_TIMER) || (cmd->convert_src == TRIG_NOW))) { /* double timed action */
1440 if (!devpriv->usedma) {
1442 "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!");
1447 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1448 &cmd->scan_begin_arg, &cmd->convert_arg,
1449 devpriv->ai_flags, devpriv->ai_n_realscanlen,
1450 &devpriv->ai_divisor1, &devpriv->ai_divisor2,
1451 devpriv->usessh, devpriv->ai_add_front);
1452 devpriv->ai_timer1 = cmd->scan_begin_arg;
1453 devpriv->ai_timer2 = cmd->convert_arg;
1456 if ((cmd->scan_begin_src == TRIG_FOLLOW)
1457 && (cmd->convert_src == TRIG_EXT)) {
1461 start_pacer(dev, -1, 0, 0); /* stop pacer */
1463 devpriv->AdControlReg = 0; /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable DMA */
1464 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1465 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */
1466 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1468 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1469 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D and INT status register */
1470 inl(dev->iobase + PCI9118_INTSRC);
1472 devpriv->ai_act_scan = 0;
1473 devpriv->ai_act_dmapos = 0;
1474 s->async->cur_chan = 0;
1475 devpriv->ai_buf_ptr = 0;
1477 if (devpriv->usedma)
1478 ret = pci9118_ai_docmd_dma(dev, s);
1480 ret = pci9118_ai_docmd_sampl(dev, s);
1482 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1487 ==============================================================================
1489 static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
1490 int n_chan, unsigned int *chanlist, int frontadd, int backadd)
1492 unsigned int i, differencial = 0, bipolar = 0;
1494 /* correct channel and range number check itself comedi/range.c */
1496 comedi_error(dev, "range/channel list is empty!");
1499 if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1501 ("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
1503 s->len_chanlist - frontadd - backadd);
1507 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1508 differencial = 1; /* all input must be diff */
1509 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1510 bipolar = 1; /* all input must be bipolar */
1512 for (i = 1; i < n_chan; i++) { /* check S.E/diff */
1513 if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1516 "Differencial and single ended inputs cann't be mixtured!");
1519 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1522 "Bipolar and unipolar ranges cann't be mixtured!");
1525 if ((!devpriv->usemux) & (differencial) &
1526 (CR_CHAN(chanlist[i]) >=
1527 this_board->n_aichand)) {
1529 "If AREF_DIFF is used then is available only first 8 channels!");
1538 ==============================================================================
1540 static int setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
1541 int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
1542 int usedma, char useeos)
1544 unsigned int i, differencial = 0, bipolar = 0;
1545 unsigned int scanquad, gain, ssh = 0x00;
1547 DPRINTK("adl_pci9118 EDBG: BGN: setup_channel_list(%d,.,%d,.,%d,%d,%d,%d)\n", dev->minor, n_chan, rot, frontadd, backadd, usedma);
1554 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1555 differencial = 1; /* all input must be diff */
1556 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1557 bipolar = 1; /* all input must be bipolar */
1559 /* All is ok, so we can setup channel/range list */
1562 devpriv->AdControlReg |= AdControl_UniP; /* set unibipolar */
1564 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); /* enable bipolar */
1568 devpriv->AdControlReg |= AdControl_Diff; /* enable diff inputs */
1570 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); /* set single ended inputs */
1573 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* setup mode */
1575 outl(2, dev->iobase + PCI9118_SCANMOD); /* gods know why this sequence! */
1576 outl(0, dev->iobase + PCI9118_SCANMOD);
1577 outl(1, dev->iobase + PCI9118_SCANMOD);
1579 #ifdef PCI9118_PARANOIDCHECK
1580 devpriv->chanlistlen = n_chan;
1581 for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1582 devpriv->chanlist[i] = 0x55aa;
1585 if (frontadd) { /* insert channels for S&H */
1586 ssh = devpriv->softsshsample;
1587 DPRINTK("FA: %04x: ", ssh);
1588 for (i = 0; i < frontadd; i++) { /* store range list to card */
1589 scanquad = CR_CHAN(chanlist[0]); /* get channel number; */
1590 gain = CR_RANGE(chanlist[0]); /* get gain number */
1591 scanquad |= ((gain & 0x03) << 8);
1592 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1593 DPRINTK("%02x ", scanquad | ssh);
1594 ssh = devpriv->softsshhold;
1599 DPRINTK("SL: ", ssh);
1600 for (i = 0; i < n_chan; i++) { /* store range list to card */
1601 scanquad = CR_CHAN(chanlist[i]); /* get channel number; */
1602 #ifdef PCI9118_PARANOIDCHECK
1603 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1605 gain = CR_RANGE(chanlist[i]); /* get gain number */
1606 scanquad |= ((gain & 0x03) << 8);
1607 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1608 DPRINTK("%02x ", scanquad | ssh);
1612 if (backadd) { /* insert channels for fit onto 32bit DMA */
1613 DPRINTK("BA: %04x: ", ssh);
1614 for (i = 0; i < backadd; i++) { /* store range list to card */
1615 scanquad = CR_CHAN(chanlist[0]); /* get channel number; */
1616 gain = CR_RANGE(chanlist[0]); /* get gain number */
1617 scanquad |= ((gain & 0x03) << 8);
1618 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1619 DPRINTK("%02x ", scanquad | ssh);
1623 #ifdef PCI9118_PARANOIDCHECK
1624 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; /* for 32bit oerations */
1626 for (i = 1; i < n_chan; i++) { /* store range list to card */
1627 devpriv->chanlist[(n_chan + i) ^ usedma] =
1628 (CR_CHAN(chanlist[i]) & 0xf) << rot;
1630 devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma]; /* for 32bit oerations */
1635 #ifdef PCI9118_EXTDEBUG
1637 for (i = 0; i <= (useeos * n_chan); i++) {
1638 DPRINTK("%04x ", devpriv->chanlist[i]);
1643 outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
1644 /* udelay(100); important delay, or first sample will be cripled */
1646 DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1647 return 1; /* we can serve this with scan logic */
1651 ==============================================================================
1652 calculate 8254 divisors if they are used for dual timing
1654 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1655 struct comedi_subdevice *s, unsigned int *tim1, unsigned int *tim2,
1656 unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
1657 char usessh, unsigned int chnsshfront)
1659 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_calc_divisors(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1663 if (*tim2 < this_board->ai_ns_min)
1664 *tim2 = this_board->ai_ns_min;
1665 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1666 tim2, flags & TRIG_ROUND_NEAREST);
1667 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1668 devpriv->i8254_osc_base, *div1, *div2, *tim1);
1671 if (*tim2 < this_board->ai_ns_min)
1672 *tim2 = this_board->ai_ns_min;
1673 DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1675 *div1 = *tim2 / devpriv->i8254_osc_base; /* convert timer (burst) */
1676 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1678 if (*div1 < this_board->ai_pacer_min)
1679 *div1 = this_board->ai_pacer_min;
1680 DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1682 *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */
1683 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1685 *div2 = *div2 / *div1; /* major timer is c1*c2 */
1686 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1690 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1693 *tim2 = *div1 * devpriv->i8254_osc_base; /* real convert timer */
1695 if (usessh & (chnsshfront == 0)) /* use BSSH signal */
1696 if (*div2 < (chans + 2))
1699 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1701 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
1702 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
1703 devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
1706 DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
1711 ==============================================================================
1713 static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
1714 unsigned int divisor2)
1716 outl(0x74, dev->iobase + PCI9118_CNTCTRL);
1717 outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
1718 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
1721 if ((mode == 1) || (mode == 2) || (mode == 4)) {
1722 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
1723 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
1724 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
1725 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
1730 ==============================================================================
1732 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
1735 return -1; /* incorrect source */
1736 devpriv->exttrg_users |= (1 << source);
1737 devpriv->IntControlReg |= Int_DTrg;
1738 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1739 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow INT in AMCC */
1744 ==============================================================================
1746 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
1749 return -1; /* incorrect source */
1750 devpriv->exttrg_users &= ~(1 << source);
1751 if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */
1752 devpriv->IntControlReg &= ~Int_DTrg;
1753 if (!devpriv->IntControlReg) /* all IRQ disabled */
1754 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & (~0x00001f00), devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* disable int in AMCC */
1755 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1761 ==============================================================================
1763 static int pci9118_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1765 if (devpriv->usedma)
1766 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
1767 pci9118_exttrg_del(dev, EXTTRG_AI);
1768 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
1769 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1770 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */
1771 devpriv->AdControlReg = 0x00;
1772 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA */
1773 outl(0, dev->iobase + PCI9118_BURST);
1774 outl(1, dev->iobase + PCI9118_SCANMOD);
1775 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
1776 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1779 devpriv->usedma = 0;
1781 devpriv->ai_act_scan = 0;
1782 devpriv->ai_act_dmapos = 0;
1783 s->async->cur_chan = 0;
1784 s->async->inttrig = NULL;
1785 devpriv->ai_buf_ptr = 0;
1786 devpriv->ai_neverending = 0;
1787 devpriv->dma_actbuf = 0;
1789 if (!devpriv->IntControlReg)
1790 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow INT in AMCC */
1796 ==============================================================================
1798 static int pci9118_reset(struct comedi_device *dev)
1800 devpriv->IntControlReg = 0;
1801 devpriv->exttrg_users = 0;
1802 inl(dev->iobase + PCI9118_INTCTRL);
1803 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); /* disable interrupts source */
1804 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1805 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
1806 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
1807 devpriv->AdControlReg = 0;
1808 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA */
1809 outl(0, dev->iobase + PCI9118_BURST);
1810 outl(1, dev->iobase + PCI9118_SCANMOD);
1811 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
1812 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1813 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */
1815 devpriv->ao_data[0] = 2047;
1816 devpriv->ao_data[1] = 2047;
1817 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1); /* reset A/D outs to 0V */
1818 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
1819 outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */
1821 inl(dev->iobase + PCI9118_AD_DATA);
1822 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1823 outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */
1824 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */
1825 inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */
1826 devpriv->AdControlReg = 0;
1827 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA */
1829 devpriv->cnt0_users = 0;
1830 devpriv->exttrg_users = 0;
1836 ==============================================================================
1838 static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1840 struct comedi_subdevice *s;
1842 unsigned short master;
1844 unsigned long iobase_a, iobase_9;
1845 struct pci_dev *pcidev;
1846 int opt_bus, opt_slot;
1848 unsigned char pci_bus, pci_slot, pci_func;
1851 printk("comedi%d: adl_pci9118: board=%s", dev->minor,
1854 opt_bus = it->options[0];
1855 opt_slot = it->options[1];
1856 if (it->options[3] & 1) {
1857 master = 0; /* user don't want use bus master */
1862 ret = alloc_private(dev, sizeof(struct pci9118_private));
1864 printk(" - Allocation failed!\n");
1868 /* Look for matching PCI device */
1869 errstr = "not found!";
1871 while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
1872 this_board->device_id, pcidev))) {
1873 /* Found matching vendor/device. */
1874 if (opt_bus || opt_slot) {
1875 /* Check bus/slot. */
1876 if (opt_bus != pcidev->bus->number
1877 || opt_slot != PCI_SLOT(pcidev->devfn))
1878 continue; /* no match */
1881 * Look for device that isn't in use.
1882 * Enable PCI device and request regions.
1884 if (comedi_pci_enable(pcidev, "adl_pci9118")) {
1885 errstr = "failed to enable PCI device and request regions!";
1892 if (opt_bus || opt_slot) {
1893 printk(" - Card at b:s %d:%d %s\n",
1894 opt_bus, opt_slot, errstr);
1896 printk(" - Card %s\n", errstr);
1902 pci_set_master(pcidev);
1905 pci_bus = pcidev->bus->number;
1906 pci_slot = PCI_SLOT(pcidev->devfn);
1907 pci_func = PCI_FUNC(pcidev->devfn);
1909 iobase_a = pci_resource_start(pcidev, 0);
1910 iobase_9 = pci_resource_start(pcidev, 2);
1912 printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot,
1913 pci_func, iobase_9, iobase_a);
1915 dev->iobase = iobase_9;
1916 dev->board_name = this_board->name;
1918 devpriv->pcidev = pcidev;
1919 devpriv->iobase_a = iobase_a;
1923 if (it->options[3] & 2)
1924 irq = 0; /* user don't want use IRQ */
1926 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
1927 "ADLink PCI-9118", dev)) {
1928 printk(", unable to allocate IRQ %d, DISABLING IT",
1930 irq = 0; /* Can't use IRQ */
1932 printk(", irq=%u", irq);
1935 printk(", IRQ disabled");
1940 if (master) { /* alloc DMA buffers */
1941 devpriv->dma_doublebuf = 0;
1942 for (i = 0; i < 2; i++) {
1943 for (pages = 4; pages >= 0; pages--) {
1944 devpriv->dmabuf_virt[i] =
1945 (short *) __get_free_pages(GFP_KERNEL,
1947 if (devpriv->dmabuf_virt[i])
1950 if (devpriv->dmabuf_virt[i]) {
1951 devpriv->dmabuf_pages[i] = pages;
1952 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
1953 devpriv->dmabuf_samples[i] =
1954 devpriv->dmabuf_size[i] >> 1;
1955 devpriv->dmabuf_hw[i] =
1956 virt_to_bus((void *)devpriv->
1960 if (!devpriv->dmabuf_virt[0]) {
1961 printk(", Can't allocate DMA buffer, DMA disabled!");
1965 if (devpriv->dmabuf_virt[1])
1966 devpriv->dma_doublebuf = 1;
1970 devpriv->master = master;
1971 if (devpriv->master)
1972 printk(", bus master");
1974 printk(", no bus master");
1976 devpriv->usemux = 0;
1977 if (it->options[2] > 0) {
1978 devpriv->usemux = it->options[2];
1979 if (devpriv->usemux > 256)
1980 devpriv->usemux = 256; /* max 256 channels! */
1981 if (it->options[4] > 0)
1982 if (devpriv->usemux > 128) {
1983 devpriv->usemux = 128; /* max 128 channels with softare S&H! */
1985 printk(", ext. mux %d channels", devpriv->usemux);
1988 devpriv->softsshdelay = it->options[4];
1989 if (devpriv->softsshdelay < 0) { /* select sample&hold signal polarity */
1990 devpriv->softsshdelay = -devpriv->softsshdelay;
1991 devpriv->softsshsample = 0x80;
1992 devpriv->softsshhold = 0x00;
1994 devpriv->softsshsample = 0x00;
1995 devpriv->softsshhold = 0x80;
2000 pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
2001 pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */
2003 ret = alloc_subdevices(dev, 4);
2007 s = dev->subdevices + 0;
2008 dev->read_subdev = s;
2009 s->type = COMEDI_SUBD_AI;
2010 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2011 if (devpriv->usemux) {
2012 s->n_chan = devpriv->usemux;
2014 s->n_chan = this_board->n_aichan;
2016 s->maxdata = this_board->ai_maxdata;
2017 s->len_chanlist = this_board->n_aichanlist;
2018 s->range_table = this_board->rangelist_ai;
2019 s->cancel = pci9118_ai_cancel;
2020 s->insn_read = pci9118_insn_read_ai;
2022 s->subdev_flags |= SDF_CMD_READ;
2023 s->do_cmdtest = pci9118_ai_cmdtest;
2024 s->do_cmd = pci9118_ai_cmd;
2025 s->munge = pci9118_ai_munge;
2028 s = dev->subdevices + 1;
2029 s->type = COMEDI_SUBD_AO;
2030 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2031 s->n_chan = this_board->n_aochan;
2032 s->maxdata = this_board->ao_maxdata;
2033 s->len_chanlist = this_board->n_aochan;
2034 s->range_table = this_board->rangelist_ao;
2035 s->insn_write = pci9118_insn_write_ao;
2036 s->insn_read = pci9118_insn_read_ao;
2038 s = dev->subdevices + 2;
2039 s->type = COMEDI_SUBD_DI;
2040 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2043 s->len_chanlist = 4;
2044 s->range_table = &range_digital;
2045 s->io_bits = 0; /* all bits input */
2046 s->insn_bits = pci9118_insn_bits_di;
2048 s = dev->subdevices + 3;
2049 s->type = COMEDI_SUBD_DO;
2050 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2053 s->len_chanlist = 4;
2054 s->range_table = &range_digital;
2055 s->io_bits = 0xf; /* all bits output */
2056 s->insn_bits = pci9118_insn_bits_do;
2059 devpriv->i8254_osc_base = 250; /* 250ns=4MHz */
2060 devpriv->ai_maskharderr = 0x10a; /* default measure crash condition */
2061 if (it->options[5]) /* disable some requested */
2062 devpriv->ai_maskharderr &= ~it->options[5];
2064 switch (this_board->ai_maxdata) {
2066 devpriv->ai16bits = 1;
2069 devpriv->ai16bits = 0;
2076 ==============================================================================
2078 static int pci9118_detach(struct comedi_device *dev)
2084 free_irq(dev->irq, dev);
2085 if (devpriv->pcidev) {
2087 comedi_pci_disable(devpriv->pcidev);
2089 pci_dev_put(devpriv->pcidev);
2091 if (devpriv->dmabuf_virt[0])
2092 free_pages((unsigned long)devpriv->dmabuf_virt[0],
2093 devpriv->dmabuf_pages[0]);
2094 if (devpriv->dmabuf_virt[1])
2095 free_pages((unsigned long)devpriv->dmabuf_virt[1],
2096 devpriv->dmabuf_pages[1]);
2103 ==============================================================================