Merge branch 'fix/asoc' into for-linus
[pandora-kernel.git] / drivers / staging / comedi / drivers / adl_pci9118.c
1 /*
2  *  comedi/drivers/adl_pci9118.c
3  *
4  *  hardware driver for ADLink cards:
5  *   card:   PCI-9118DG, PCI-9118HG, PCI-9118HR
6  *   driver: pci9118dg,  pci9118hg,  pci9118hr
7  *
8  * Author: Michal Dobes <dobes@tesnet.cz>
9  *
10 */
11 /*
12 Driver: adl_pci9118
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)
17 Status: works
18
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.
22 For AI:
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
30   ranges).
31
32 There are some hardware limitations:
33 a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
34    ended inputs.
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.
43
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
48           card will be used.
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
52         1=disable DMA mode
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
63
64 */
65 #include "../comedidev.h"
66 #include "../pci_ids.h"
67
68 #include <linux/delay.h>
69
70 #include "amcc_s5933.h"
71 #include "8253.h"
72 #include "comedi_pci.h"
73 #include "comedi_fc.h"
74
75 /* paranoid checks are broken */
76 #undef PCI9118_PARANOIDCHECK    /* if defined, then is used code which control correct channel number on every 12 bit sample */
77
78 #undef PCI9118_EXTDEBUG         /* if defined then driver prints a lot of messages */
79
80 #undef DPRINTK
81 #ifdef PCI9118_EXTDEBUG
82 #define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
83 #else
84 #define DPRINTK(fmt, args...)
85 #endif
86
87 #define IORANGE_9118    64      /* I hope */
88 #define PCI9118_CHANLEN 255     /* len of chanlist, some source say 256, but reality looks like 255 :-( */
89
90 #define PCI9118_CNT0    0x00    /* R/W: 8254 couter 0 */
91 #define PCI9118_CNT1    0x04    /* R/W: 8254 couter 0 */
92 #define PCI9118_CNT2    0x08    /* R/W: 8254 couter 0 */
93 #define PCI9118_CNTCTRL 0x0c    /* W:   8254 counter control */
94 #define PCI9118_AD_DATA 0x10    /* R:   A/D data */
95 #define PCI9118_DA1     0x10    /* W:   D/A registers */
96 #define PCI9118_DA2     0x14
97 #define PCI9118_ADSTAT  0x18    /* R:   A/D status register */
98 #define PCI9118_ADCNTRL 0x18    /* W:   A/D control register */
99 #define PCI9118_DI      0x1c    /* R:   digi input register */
100 #define PCI9118_DO      0x1c    /* W:   digi output register */
101 #define PCI9118_SOFTTRG 0x20    /* W:   soft trigger for A/D */
102 #define PCI9118_GAIN    0x24    /* W:   A/D gain/channel register */
103 #define PCI9118_BURST   0x28    /* W:   A/D burst number register */
104 #define PCI9118_SCANMOD 0x2c    /* W:   A/D auto scan mode */
105 #define PCI9118_ADFUNC  0x30    /* W:   A/D function register */
106 #define PCI9118_DELFIFO 0x34    /* W:   A/D data FIFO reset */
107 #define PCI9118_INTSRC  0x38    /* R:   interrupt reason register */
108 #define PCI9118_INTCTRL 0x38    /* W:   interrupt control register */
109
110 // bits from A/D control register (PCI9118_ADCNTRL)
111 #define AdControl_UniP  0x80    /* 1=bipolar, 0=unipolar */
112 #define AdControl_Diff  0x40    /* 1=differential, 0= single end inputs */
113 #define AdControl_SoftG 0x20    /* 1=8254 counter works, 0=counter stops */
114 #define AdControl_ExtG  0x10    /* 1=8254 countrol controlled by TGIN(pin 46), 0=controled by SoftG */
115 #define AdControl_ExtM  0x08    /* 1=external hardware trigger (pin 44), 0=internal trigger */
116 #define AdControl_TmrTr 0x04    /* 1=8254 is iternal trigger source, 0=software trigger is source (register PCI9118_SOFTTRG) */
117 #define AdControl_Int   0x02    /* 1=enable INT, 0=disable */
118 #define AdControl_Dma   0x01    /* 1=enable DMA, 0=disable */
119
120 // bits from A/D function register (PCI9118_ADFUNC)
121 #define AdFunction_PDTrg        0x80    /* 1=positive, 0=negative digital trigger (only positive is correct) */
122 #define AdFunction_PETrg        0x40    /* 1=positive, 0=negative external trigger (only positive is correct) */
123 #define AdFunction_BSSH         0x20    /* 1=with sample&hold, 0=without */
124 #define AdFunction_BM           0x10    /* 1=burst mode, 0=normal mode */
125 #define AdFunction_BS           0x08    /* 1=burst mode start, 0=burst mode stop */
126 #define AdFunction_PM           0x04    /* 1=post trigger mode, 0=not post trigger */
127 #define AdFunction_AM           0x02    /* 1=about trigger mode, 0=not about trigger */
128 #define AdFunction_Start        0x01    /* 1=trigger start, 0=trigger stop */
129
130 // bits from A/D status register (PCI9118_ADSTAT)
131 #define AdStatus_nFull  0x100   /* 0=FIFO full (fatal), 1=not full */
132 #define AdStatus_nHfull 0x080   /* 0=FIFO half full, 1=FIFO not half full */
133 #define AdStatus_nEpty  0x040   /* 0=FIFO empty, 1=FIFO not empty */
134 #define AdStatus_Acmp   0x020   /*  */
135 #define AdStatus_DTH    0x010   /* 1=external digital trigger */
136 #define AdStatus_Bover  0x008   /* 1=burst mode overrun (fatal) */
137 #define AdStatus_ADOS   0x004   /* 1=A/D over speed (warning) */
138 #define AdStatus_ADOR   0x002   /* 1=A/D overrun (fatal) */
139 #define AdStatus_ADrdy  0x001   /* 1=A/D already ready, 0=not ready */
140
141 // bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL)
142 // 1=interrupt occur, enable source,  0=interrupt not occur, disable source
143 #define Int_Timer       0x08    /* timer interrupt */
144 #define Int_About       0x04    /* about trigger complete */
145 #define Int_Hfull       0x02    /* A/D FIFO hlaf full */
146 #define Int_DTrg        0x01    /* external digital trigger */
147
148 #define START_AI_EXT    0x01    /* start measure on external trigger */
149 #define STOP_AI_EXT     0x02    /* stop measure on external trigger */
150 #define START_AI_INT    0x04    /* start measure on internal trigger */
151 #define STOP_AI_INT     0x08    /* stop measure on internal trigger */
152
153 #define EXTTRG_AI       0       /* ext trg is used by AI */
154
155 static const struct comedi_lrange range_pci9118dg_hr = { 8, {
156                         BIP_RANGE(5),
157                         BIP_RANGE(2.5),
158                         BIP_RANGE(1.25),
159                         BIP_RANGE(0.625),
160                         UNI_RANGE(10),
161                         UNI_RANGE(5),
162                         UNI_RANGE(2.5),
163                         UNI_RANGE(1.25)
164         }
165 };
166
167 static const struct comedi_lrange range_pci9118hg = { 8, {
168                         BIP_RANGE(5),
169                         BIP_RANGE(0.5),
170                         BIP_RANGE(0.05),
171                         BIP_RANGE(0.005),
172                         UNI_RANGE(10),
173                         UNI_RANGE(1),
174                         UNI_RANGE(0.1),
175                         UNI_RANGE(0.01)
176         }
177 };
178
179 #define PCI9118_BIPOLAR_RANGES  4       /* used for test on mixture of BIP/UNI ranges */
180
181 static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it);
182 static int pci9118_detach(struct comedi_device * dev);
183
184 struct boardtype {
185         const char *name;       // board name
186         int vendor_id;          // PCI vendor a device ID of card
187         int device_id;
188         int iorange_amcc;       // iorange for own S5933 region
189         int iorange_9118;       // pass thru card region size
190         int n_aichan;           // num of A/D chans
191         int n_aichand;          // num of A/D chans in diff mode
192         int mux_aichan;         // num of A/D chans with external multiplexor
193         int n_aichanlist;       // len of chanlist
194         int n_aochan;           // num of D/A chans
195         int ai_maxdata;         // resolution of A/D
196         int ao_maxdata;         // resolution of D/A
197         const struct comedi_lrange *rangelist_ai;       // rangelist for A/D
198         const struct comedi_lrange *rangelist_ao;       // rangelist for D/A
199         unsigned int ai_ns_min; // max sample speed of card v ns
200         unsigned int ai_pacer_min;      // minimal pacer value (c1*c2 or c1 in burst)
201         int half_fifo_size;     // size of FIFO/2
202
203 };
204
205 static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
206         {PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
207         {0}
208 };
209
210 MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
211
212 static const struct boardtype boardtypes[] = {
213         {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
214                         AMCC_OP_REG_SIZE, IORANGE_9118,
215                         16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
216                         &range_pci9118dg_hr, &range_bipolar10,
217                 3000, 12, 512},
218         {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
219                         AMCC_OP_REG_SIZE, IORANGE_9118,
220                         16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
221                         &range_pci9118hg, &range_bipolar10,
222                 3000, 12, 512},
223         {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
224                         AMCC_OP_REG_SIZE, IORANGE_9118,
225                         16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
226                         &range_pci9118dg_hr, &range_bipolar10,
227                 10000, 40, 512},
228 };
229
230 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
231
232 static struct comedi_driver driver_pci9118 = {
233       driver_name:"adl_pci9118",
234       module:THIS_MODULE,
235       attach:pci9118_attach,
236       detach:pci9118_detach,
237       num_names:n_boardtypes,
238       board_name:&boardtypes[0].name,
239       offset:sizeof(struct boardtype),
240 };
241
242 COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
243
244 struct pci9118_private {
245         unsigned long iobase_a; // base+size for AMCC chip
246         unsigned int master;    // master capable
247         struct pci_dev *pcidev; // ptr to actual pcidev
248         unsigned int usemux;    // we want to use external multiplexor!
249 #ifdef PCI9118_PARANOIDCHECK
250         unsigned short chanlist[PCI9118_CHANLEN + 1];   // list of scaned channel
251         unsigned char chanlistlen;      // number of scanlist
252 #endif
253         unsigned char AdControlReg;     // A/D control register
254         unsigned char IntControlReg;    // Interrupt control register
255         unsigned char AdFunctionReg;    // A/D function register
256         char valid;             // driver is ok
257         char ai_neverending;    // we do unlimited AI
258         unsigned int i8254_osc_base;    // frequence of onboard oscilator
259         unsigned int ai_do;     // what do AI? 0=nothing, 1 to 4 mode
260         unsigned int ai_act_scan;       // how many scans we finished
261         unsigned int ai_buf_ptr;        // data buffer ptr in samples
262         unsigned int ai_n_chan; // how many channels is measured
263         unsigned int ai_n_scanlen;      // len of actual scanlist
264         unsigned int ai_n_realscanlen;  // what we must transfer for one outgoing scan include front/back adds
265         unsigned int ai_act_dmapos;     // position in actual real stream
266         unsigned int ai_add_front;      // how many channels we must add before scan to satisfy S&H?
267         unsigned int ai_add_back;       // how many channels we must add before scan to satisfy DMA?
268         unsigned int *ai_chanlist;      // actaul chanlist
269         unsigned int ai_timer1;
270         unsigned int ai_timer2;
271         unsigned int ai_flags;
272         char ai12_startstop;    // measure can start/stop on external trigger
273         unsigned int ai_divisor1, ai_divisor2;  // divisors for start of measure on external start
274         unsigned int ai_data_len;
275         short *ai_data;
276         short ao_data[2];       // data output buffer
277         unsigned int ai_scans;  // number of scans to do
278         char dma_doublebuf;     // we can use double buffring
279         unsigned int dma_actbuf;        // which buffer is used now
280         short *dmabuf_virt[2];  // pointers to begin of DMA buffer
281         unsigned long dmabuf_hw[2];     // hw address of DMA buff
282         unsigned int dmabuf_size[2];    // size of dma buffer in bytes
283         unsigned int dmabuf_use_size[2];        // which size we may now used for transfer
284         unsigned int dmabuf_used_size[2];       // which size was trully used
285         unsigned int dmabuf_panic_size[2];
286         unsigned int dmabuf_samples[2]; // size in samples
287         int dmabuf_pages[2];    // number of pages in buffer
288         unsigned char cnt0_users;       // bit field of 8254 CNT0 users (0-unused, 1-AO, 2-DI, 3-DO)
289         unsigned char exttrg_users;     // bit field of external trigger users (0-AI, 1-AO, 2-DI, 3-DO)
290         unsigned int cnt0_divisor;      // actual CNT0 divisor
291         void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, unsigned short, unsigned int, unsigned short);  // ptr to actual interrupt AI function
292         unsigned char ai16bits; // =1 16 bit card
293         unsigned char usedma;   // =1 use DMA transfer and not INT
294         unsigned char useeoshandle;     // =1 change WAKE_EOS DMA transfer to fit on every second
295         unsigned char usessh;   // =1 turn on S&H support
296         int softsshdelay;       // >0 use software S&H, numer is requested delay in ns
297         unsigned char softsshsample;    // polarity of S&H signal in sample state
298         unsigned char softsshhold;      // polarity of S&H signal in hold state
299         unsigned int ai_maskerr;        // which warning was printed
300         unsigned int ai_maskharderr;    // on which error bits stops
301         unsigned int ai_inttrig_start;  // TRIG_INT for start
302 };
303
304 #define devpriv ((struct pci9118_private *)dev->private)
305 #define this_board ((struct boardtype *)dev->board_ptr)
306
307 /*
308 ==============================================================================
309 */
310
311 static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
312         int n_chan, unsigned int *chanlist, int frontadd, int backadd);
313 static int setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
314         int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
315         int usedma, char eoshandle);
316 static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
317         unsigned int divisor2);
318 static int pci9118_reset(struct comedi_device * dev);
319 static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source);
320 static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source);
321 static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
322 static void pci9118_calc_divisors(char mode, struct comedi_device * dev,
323         struct comedi_subdevice * s, unsigned int *tim1, unsigned int *tim2,
324         unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
325         char usessh, unsigned int chnsshfront);
326
327 /*
328 ==============================================================================
329 */
330 static int pci9118_insn_read_ai(struct comedi_device * dev, struct comedi_subdevice * s,
331         struct comedi_insn * insn, unsigned int * data)
332 {
333
334         int n, timeout;
335
336         devpriv->AdControlReg = AdControl_Int & 0xff;
337         devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
338         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);     // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
339
340         if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
341                 return -EINVAL;
342
343         outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
344
345         for (n = 0; n < insn->n; n++) {
346                 outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
347                 comedi_udelay(2);
348                 timeout = 100;
349                 while (timeout--) {
350                         if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
351                                 goto conv_finish;
352                         comedi_udelay(1);
353                 }
354
355                 comedi_error(dev, "A/D insn timeout");
356                 data[n] = 0;
357                 outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
358                 return -ETIME;
359
360               conv_finish:
361                 if (devpriv->ai16bits) {
362                         data[n] =
363                                 (inl(dev->iobase +
364                                         PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
365                 } else {
366                         data[n] =
367                                 (inw(dev->iobase +
368                                         PCI9118_AD_DATA) >> 4) & 0xfff;
369                 }
370         }
371
372         outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
373         return n;
374
375 }
376
377 /*
378 ==============================================================================
379 */
380 static int pci9118_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
381         struct comedi_insn * insn, unsigned int * data)
382 {
383         int n, chanreg, ch;
384
385         ch = CR_CHAN(insn->chanspec);
386         if (ch) {
387                 chanreg = PCI9118_DA2;
388         } else {
389                 chanreg = PCI9118_DA1;
390         }
391
392         for (n = 0; n < insn->n; n++) {
393                 outl(data[n], dev->iobase + chanreg);
394                 devpriv->ao_data[ch] = data[n];
395         }
396
397         return n;
398 }
399
400 /*
401 ==============================================================================
402 */
403 static int pci9118_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
404         struct comedi_insn * insn, unsigned int * data)
405 {
406         int n, chan;
407
408         chan = CR_CHAN(insn->chanspec);
409         for (n = 0; n < insn->n; n++)
410                 data[n] = devpriv->ao_data[chan];
411
412         return n;
413 }
414
415 /*
416 ==============================================================================
417 */
418 static int pci9118_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
419         struct comedi_insn * insn, unsigned int * data)
420 {
421         data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
422
423         return 2;
424 }
425
426 /*
427 ==============================================================================
428 */
429 static int pci9118_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
430         struct comedi_insn * insn, unsigned int * data)
431 {
432         if (data[0]) {
433                 s->state &= ~data[0];
434                 s->state |= (data[0] & data[1]);
435                 outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
436         }
437         data[1] = s->state;
438
439         return 2;
440 }
441
442 /*
443 ==============================================================================
444 */
445 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device * dev)
446 {
447         devpriv->AdFunctionReg =
448                 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
449         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
450         outl(0x30, dev->iobase + PCI9118_CNTCTRL);
451         outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
452                 dev->iobase + PCI9118_CNT0);
453         outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
454                 dev->iobase + PCI9118_CNT0);
455         devpriv->AdFunctionReg |= AdFunction_Start;
456         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
457 }
458
459 static unsigned int defragment_dma_buffer(struct comedi_device * dev,
460         struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
461 {
462         unsigned int i = 0, j = 0;
463         unsigned int start_pos = devpriv->ai_add_front,
464                 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
465         unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
466                 devpriv->ai_add_back;
467
468         for (i = 0; i < num_samples; i++) {
469                 if (devpriv->ai_act_dmapos >= start_pos &&
470                         devpriv->ai_act_dmapos < stop_pos) {
471                         dma_buffer[j++] = dma_buffer[i];
472                 }
473                 devpriv->ai_act_dmapos++;
474                 devpriv->ai_act_dmapos %= raw_scanlen;
475         }
476
477         return j;
478 }
479
480 /*
481 ==============================================================================
482 */
483 static unsigned int move_block_from_dma(struct comedi_device * dev,
484         struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
485 {
486         unsigned int num_bytes;
487
488         num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
489         devpriv->ai_act_scan +=
490                 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
491         s->async->cur_chan += num_samples;
492         s->async->cur_chan %= devpriv->ai_n_scanlen;
493         num_bytes =
494                 cfc_write_array_to_buffer(s, dma_buffer,
495                 num_samples * sizeof(short));
496         if (num_bytes < num_samples * sizeof(short))
497                 return -1;
498         return 0;
499 }
500
501 /*
502 ==============================================================================
503 */
504 static char pci9118_decode_error_status(struct comedi_device * dev,
505         struct comedi_subdevice * s, unsigned char m)
506 {
507         if (m & 0x100) {
508                 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
509                 devpriv->ai_maskerr &= ~0x100L;
510         }
511         if (m & 0x008) {
512                 comedi_error(dev,
513                         "A/D Burst Mode Overrun Status (Fatal Error!)");
514                 devpriv->ai_maskerr &= ~0x008L;
515         }
516         if (m & 0x004) {
517                 comedi_error(dev, "A/D Over Speed Status (Warning!)");
518                 devpriv->ai_maskerr &= ~0x004L;
519         }
520         if (m & 0x002) {
521                 comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
522                 devpriv->ai_maskerr &= ~0x002L;
523         }
524         if (m & devpriv->ai_maskharderr) {
525                 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
526                 pci9118_ai_cancel(dev, s);
527                 comedi_event(dev, s);
528                 return 1;
529         }
530
531         return 0;
532 }
533
534 static void pci9118_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
535         void *data, unsigned int num_bytes, unsigned int start_chan_index)
536 {
537         unsigned int i, num_samples = num_bytes / sizeof(short);
538         short *array = data;
539
540         for (i = 0; i < num_samples; i++) {
541                 if (devpriv->usedma)
542                         array[i] = be16_to_cpu(array[i]);
543                 if (devpriv->ai16bits) {
544                         array[i] ^= 0x8000;
545                 } else {
546                         array[i] = (array[i] >> 4) & 0x0fff;
547                 }
548         }
549 }
550
551 /*
552 ==============================================================================
553 */
554 static void interrupt_pci9118_ai_onesample(struct comedi_device * dev,
555         struct comedi_subdevice * s, unsigned short int_adstat, unsigned int int_amcc,
556         unsigned short int_daq)
557 {
558         register short sampl;
559
560         s->async->events = 0;
561
562         if (int_adstat & devpriv->ai_maskerr)
563                 if (pci9118_decode_error_status(dev, s, int_adstat))
564                         return;
565
566         sampl = inw(dev->iobase + PCI9118_AD_DATA);
567
568 #ifdef PCI9118_PARANOIDCHECK
569         if (devpriv->ai16bits == 0) {
570                 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {        // data dropout!
571                         rt_printk
572                                 ("comedi: A/D  SAMPL - data dropout: received channel %d, expected %d!\n",
573                                 sampl & 0x000f,
574                                 devpriv->chanlist[s->async->cur_chan]);
575                         s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
576                         pci9118_ai_cancel(dev, s);
577                         comedi_event(dev, s);
578                         return;
579                 }
580         }
581 #endif
582         cfc_write_to_buffer(s, sampl);
583         s->async->cur_chan++;
584         if (s->async->cur_chan >= devpriv->ai_n_scanlen) {      /* one scan done */
585                 s->async->cur_chan %= devpriv->ai_n_scanlen;
586                 devpriv->ai_act_scan++;
587                 if (!(devpriv->ai_neverending))
588                         if (devpriv->ai_act_scan >= devpriv->ai_scans) {        /* all data sampled */
589                                 pci9118_ai_cancel(dev, s);
590                                 s->async->events |= COMEDI_CB_EOA;
591                         }
592         }
593
594         if (s->async->events)
595                 comedi_event(dev, s);
596 }
597
598 /*
599 ==============================================================================
600 */
601 static void interrupt_pci9118_ai_dma(struct comedi_device * dev, struct comedi_subdevice * s,
602         unsigned short int_adstat, unsigned int int_amcc,
603         unsigned short int_daq)
604 {
605         unsigned int next_dma_buf, samplesinbuf, sampls, m;
606
607         if (int_amcc & MASTER_ABORT_INT) {
608                 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
609                 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
610                 pci9118_ai_cancel(dev, s);
611                 comedi_event(dev, s);
612                 return;
613         }
614
615         if (int_amcc & TARGET_ABORT_INT) {
616                 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
617                 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
618                 pci9118_ai_cancel(dev, s);
619                 comedi_event(dev, s);
620                 return;
621         }
622
623         if (int_adstat & devpriv->ai_maskerr)
624 //      if (int_adstat & 0x106)
625                 if (pci9118_decode_error_status(dev, s, int_adstat))
626                         return;
627
628         samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;      // number of received real samples
629 //      DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf);
630
631         if (devpriv->dma_doublebuf) {   // switch DMA buffers if is used double buffering
632                 next_dma_buf = 1 - devpriv->dma_actbuf;
633                 outl(devpriv->dmabuf_hw[next_dma_buf],
634                         devpriv->iobase_a + AMCC_OP_REG_MWAR);
635                 outl(devpriv->dmabuf_use_size[next_dma_buf],
636                         devpriv->iobase_a + AMCC_OP_REG_MWTC);
637                 devpriv->dmabuf_used_size[next_dma_buf] =
638                         devpriv->dmabuf_use_size[next_dma_buf];
639                 if (devpriv->ai_do == 4)
640                         interrupt_pci9118_ai_mode4_switch(dev);
641         }
642
643         if (samplesinbuf) {
644                 m = devpriv->ai_data_len >> 1;  // how many samples is to end of buffer
645 //              DPRINTK("samps=%d m=%d %d %d\n",samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);
646                 sampls = m;
647                 move_block_from_dma(dev, s,
648                         devpriv->dmabuf_virt[devpriv->dma_actbuf],
649                         samplesinbuf);
650                 m = m - sampls; // m= how many samples was transfered
651         }
652 //      DPRINTK("YYY\n");
653
654         if (!devpriv->ai_neverending)
655                 if (devpriv->ai_act_scan >= devpriv->ai_scans) {        /* all data sampled */
656                         pci9118_ai_cancel(dev, s);
657                         s->async->events |= COMEDI_CB_EOA;
658                 }
659
660         if (devpriv->dma_doublebuf) {   // switch dma buffers
661                 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
662         } else {                // restart DMA if is not used double buffering
663                 outl(devpriv->dmabuf_hw[0],
664                         devpriv->iobase_a + AMCC_OP_REG_MWAR);
665                 outl(devpriv->dmabuf_use_size[0],
666                         devpriv->iobase_a + AMCC_OP_REG_MWTC);
667                 if (devpriv->ai_do == 4)
668                         interrupt_pci9118_ai_mode4_switch(dev);
669         }
670
671         comedi_event(dev, s);
672 }
673
674 /*
675 ==============================================================================
676 */
677 static irqreturn_t interrupt_pci9118(int irq, void *d PT_REGS_ARG)
678 {
679         struct comedi_device *dev = d;
680         unsigned int int_daq = 0, int_amcc, int_adstat;
681
682         if (!dev->attached)
683                 return IRQ_NONE;        // not fully initialized
684
685         int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;      // get IRQ reasons from card
686         int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); // get INT register from AMCC chip
687
688 //      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);
689
690         if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
691                 return IRQ_NONE;        // interrupt from other source
692
693         outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);    // shutdown IRQ reasons in AMCC
694
695         int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; // get STATUS register
696
697         if (devpriv->ai_do) {
698                 if (devpriv->ai12_startstop)
699                         if ((int_adstat & AdStatus_DTH) && (int_daq & Int_DTrg)) {      // start stop of measure
700                                 if (devpriv->ai12_startstop & START_AI_EXT) {
701                                         devpriv->ai12_startstop &=
702                                                 ~START_AI_EXT;
703                                         if (!(devpriv->ai12_startstop &
704                                                         STOP_AI_EXT))
705                                                 pci9118_exttrg_del(dev, EXTTRG_AI);     // deactivate EXT trigger
706                                         start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2);   // start pacer
707                                         outl(devpriv->AdControlReg,
708                                                 dev->iobase + PCI9118_ADCNTRL);
709                                 } else {
710                                         if (devpriv->
711                                                 ai12_startstop & STOP_AI_EXT) {
712                                                 devpriv->ai12_startstop &=
713                                                         ~STOP_AI_EXT;
714                                                 pci9118_exttrg_del(dev, EXTTRG_AI);     // deactivate EXT trigger
715                                                 devpriv->ai_neverending = 0;    //well, on next interrupt from DMA/EOC measure will stop
716                                         }
717                                 }
718                         }
719
720                 (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
721                         int_amcc, int_daq);
722
723         }
724         return IRQ_HANDLED;
725 }
726
727 /*
728 ==============================================================================
729 */
730 static int pci9118_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
731         unsigned int trignum)
732 {
733         if (trignum != devpriv->ai_inttrig_start)
734                 return -EINVAL;
735
736         devpriv->ai12_startstop &= ~START_AI_INT;
737         s->async->inttrig = NULL;
738
739         outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
740         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
741         if (devpriv->ai_do != 3) {
742                 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
743                         devpriv->ai_divisor2);
744                 devpriv->AdControlReg |= AdControl_SoftG;
745         }
746         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
747
748         return 1;
749 }
750
751 /*
752 ==============================================================================
753 */
754 static int pci9118_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
755         struct comedi_cmd * cmd)
756 {
757         int err = 0;
758         int tmp, divisor1, divisor2;
759
760         /* step 1: make sure trigger sources are trivially valid */
761
762         tmp = cmd->start_src;
763         cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
764         if (!cmd->start_src || tmp != cmd->start_src)
765                 err++;
766
767         tmp = cmd->scan_begin_src;
768         if (devpriv->master) {
769                 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
770         } else {
771                 cmd->scan_begin_src &= TRIG_FOLLOW;
772         }
773         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
774                 err++;
775
776         tmp = cmd->convert_src;
777         if (devpriv->master) {
778                 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
779         } else {
780                 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
781         }
782         if (!cmd->convert_src || tmp != cmd->convert_src)
783                 err++;
784
785         tmp = cmd->scan_end_src;
786         cmd->scan_end_src &= TRIG_COUNT;
787         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
788                 err++;
789
790         tmp = cmd->stop_src;
791         cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
792         if (!cmd->stop_src || tmp != cmd->stop_src)
793                 err++;
794
795         if (err)
796                 return 1;
797
798         /* step 2: make sure trigger sources are unique and mutually compatible */
799
800         if (cmd->start_src != TRIG_NOW &&
801                 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
802                 cmd->start_src = TRIG_NOW;
803                 err++;
804         }
805
806         if (cmd->scan_begin_src != TRIG_TIMER &&
807                 cmd->scan_begin_src != TRIG_EXT &&
808                 cmd->scan_begin_src != TRIG_INT &&
809                 cmd->scan_begin_src != TRIG_FOLLOW) {
810                 cmd->scan_begin_src = TRIG_FOLLOW;
811                 err++;
812         }
813
814         if (cmd->convert_src != TRIG_TIMER &&
815                 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
816                 cmd->convert_src = TRIG_TIMER;
817                 err++;
818         }
819
820         if (cmd->scan_end_src != TRIG_COUNT) {
821                 cmd->scan_end_src = TRIG_COUNT;
822                 err++;
823         }
824
825         if (cmd->stop_src != TRIG_NONE &&
826                 cmd->stop_src != TRIG_COUNT &&
827                 cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
828                 cmd->stop_src = TRIG_COUNT;
829                 err++;
830         }
831
832         if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
833                 cmd->start_src = TRIG_NOW;
834                 err++;
835         }
836
837         if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
838                 cmd->start_src = TRIG_NOW;
839                 err++;
840         }
841
842         if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
843                 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
844                 cmd->convert_src = TRIG_TIMER;
845                 err++;
846         }
847
848         if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
849                 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
850                 cmd->convert_src = TRIG_TIMER;
851                 err++;
852         }
853
854         if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
855                 cmd->stop_src = TRIG_COUNT;
856                 err++;
857         }
858
859         if (err)
860                 return 2;
861
862         /* step 3: make sure arguments are trivially compatible */
863
864         if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
865                 if (cmd->start_arg != 0) {
866                         cmd->start_arg = 0;
867                         err++;
868                 }
869
870         if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
871                 if (cmd->scan_begin_arg != 0) {
872                         cmd->scan_begin_arg = 0;
873                         err++;
874                 }
875
876         if ((cmd->scan_begin_src == TRIG_TIMER) &&
877                 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
878                 cmd->scan_begin_src = TRIG_FOLLOW;
879                 cmd->convert_arg = cmd->scan_begin_arg;
880                 cmd->scan_begin_arg = 0;
881         }
882
883         if (cmd->scan_begin_src == TRIG_TIMER)
884                 if (cmd->scan_begin_arg < this_board->ai_ns_min) {
885                         cmd->scan_begin_arg = this_board->ai_ns_min;
886                         err++;
887                 }
888
889         if (cmd->scan_begin_src == TRIG_EXT)
890                 if (cmd->scan_begin_arg) {
891                         cmd->scan_begin_arg = 0;
892                         err++;
893                         if (cmd->scan_end_arg > 65535) {
894                                 cmd->scan_end_arg = 65535;
895                                 err++;
896                         }
897                 }
898
899         if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
900                 if (cmd->convert_arg < this_board->ai_ns_min) {
901                         cmd->convert_arg = this_board->ai_ns_min;
902                         err++;
903                 }
904
905         if (cmd->convert_src == TRIG_EXT)
906                 if (cmd->convert_arg) {
907                         cmd->convert_arg = 0;
908                         err++;
909                 }
910
911         if (cmd->stop_src == TRIG_COUNT) {
912                 if (!cmd->stop_arg) {
913                         cmd->stop_arg = 1;
914                         err++;
915                 }
916         } else {                /* TRIG_NONE */
917                 if (cmd->stop_arg != 0) {
918                         cmd->stop_arg = 0;
919                         err++;
920                 }
921         }
922
923         if (!cmd->chanlist_len) {
924                 cmd->chanlist_len = 1;
925                 err++;
926         }
927
928         if (cmd->chanlist_len > this_board->n_aichanlist) {
929                 cmd->chanlist_len = this_board->n_aichanlist;
930                 err++;
931         }
932
933         if (cmd->scan_end_arg < cmd->chanlist_len) {
934                 cmd->scan_end_arg = cmd->chanlist_len;
935                 err++;
936         }
937
938         if ((cmd->scan_end_arg % cmd->chanlist_len)) {
939                 cmd->scan_end_arg =
940                         cmd->chanlist_len * (cmd->scan_end_arg /
941                         cmd->chanlist_len);
942                 err++;
943         }
944
945         if (err)
946                 return 3;
947
948         /* step 4: fix up any arguments */
949
950         if (cmd->scan_begin_src == TRIG_TIMER) {
951                 tmp = cmd->scan_begin_arg;
952 //              rt_printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
953                 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
954                         &divisor2, &cmd->scan_begin_arg,
955                         cmd->flags & TRIG_ROUND_MASK);
956 //              rt_printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
957                 if (cmd->scan_begin_arg < this_board->ai_ns_min)
958                         cmd->scan_begin_arg = this_board->ai_ns_min;
959                 if (tmp != cmd->scan_begin_arg)
960                         err++;
961         }
962
963         if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
964                 tmp = cmd->convert_arg;
965                 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
966                         &divisor2, &cmd->convert_arg,
967                         cmd->flags & TRIG_ROUND_MASK);
968 //              rt_printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
969                 if (cmd->convert_arg < this_board->ai_ns_min)
970                         cmd->convert_arg = this_board->ai_ns_min;
971                 if (tmp != cmd->convert_arg)
972                         err++;
973                 if (cmd->scan_begin_src == TRIG_TIMER
974                         && cmd->convert_src == TRIG_NOW) {
975                         if (cmd->convert_arg == 0) {
976                                 if (cmd->scan_begin_arg <
977                                         this_board->ai_ns_min *
978                                         (cmd->scan_end_arg + 2)) {
979                                         cmd->scan_begin_arg =
980                                                 this_board->ai_ns_min *
981                                                 (cmd->scan_end_arg + 2);
982 //              rt_printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
983                                         err++;
984                                 }
985                         } else {
986                                 if (cmd->scan_begin_arg <
987                                         cmd->convert_arg * cmd->chanlist_len) {
988                                         cmd->scan_begin_arg =
989                                                 cmd->convert_arg *
990                                                 cmd->chanlist_len;
991 //              rt_printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
992                                         err++;
993                                 }
994                         }
995                 }
996         }
997
998         if (err)
999                 return 4;
1000
1001         if (cmd->chanlist)
1002                 if (!check_channel_list(dev, s, cmd->chanlist_len,
1003                                 cmd->chanlist, 0, 0))
1004                         return 5;       // incorrect channels list
1005
1006         return 0;
1007 }
1008
1009 /*
1010 ==============================================================================
1011 */
1012 static int Compute_and_setup_dma(struct comedi_device * dev)
1013 {
1014         unsigned int dmalen0, dmalen1, i;
1015
1016         DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
1017         dmalen0 = devpriv->dmabuf_size[0];
1018         dmalen1 = devpriv->dmabuf_size[1];
1019         DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
1020                 devpriv->ai_data_len);
1021         // isn't output buff smaller that our DMA buff?
1022         if (dmalen0 > (devpriv->ai_data_len)) {
1023                 dmalen0 = devpriv->ai_data_len & ~3L;   // allign to 32bit down
1024         }
1025         if (dmalen1 > (devpriv->ai_data_len)) {
1026                 dmalen1 = devpriv->ai_data_len & ~3L;   // allign to 32bit down
1027         }
1028         DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1029
1030         // we want wake up every scan?
1031         if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1032                 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1033                         // uff, too short DMA buffer, disable EOS support!
1034                         devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1035                         rt_printk
1036                                 ("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
1037                                 dev->minor, dmalen0,
1038                                 devpriv->ai_n_realscanlen << 1);
1039                 } else {
1040                         // short first DMA buffer to one scan
1041                         dmalen0 = devpriv->ai_n_realscanlen << 1;
1042                         DPRINTK("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen0, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
1043                         if (devpriv->useeoshandle)
1044                                 dmalen0 += 2;
1045                         if (dmalen0 < 4) {
1046                                 rt_printk
1047                                         ("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
1048                                         dev->minor, dmalen0);
1049                                 dmalen0 = 4;
1050                         }
1051                 }
1052         }
1053         if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1054                 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1055                         // uff, too short DMA buffer, disable EOS support!
1056                         devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1057                         rt_printk
1058                                 ("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
1059                                 dev->minor, dmalen1,
1060                                 devpriv->ai_n_realscanlen << 1);
1061                 } else {
1062                         // short second DMA buffer to one scan
1063                         dmalen1 = devpriv->ai_n_realscanlen << 1;
1064                         DPRINTK("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen1, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
1065                         if (devpriv->useeoshandle)
1066                                 dmalen1 -= 2;
1067                         if (dmalen1 < 4) {
1068                                 rt_printk
1069                                         ("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
1070                                         dev->minor, dmalen1);
1071                                 dmalen1 = 4;
1072                         }
1073                 }
1074         }
1075
1076         DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1077         // transfer without TRIG_WAKE_EOS
1078         if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1079                 // if it's possible then allign DMA buffers to length of scan
1080                 i = dmalen0;
1081                 dmalen0 =
1082                         (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1083                         (devpriv->ai_n_realscanlen << 1);
1084                 dmalen0 &= ~3L;
1085                 if (!dmalen0)
1086                         dmalen0 = i;    // uff. very long scan?
1087                 i = dmalen1;
1088                 dmalen1 =
1089                         (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1090                         (devpriv->ai_n_realscanlen << 1);
1091                 dmalen1 &= ~3L;
1092                 if (!dmalen1)
1093                         dmalen1 = i;    // uff. very long scan?
1094                 // if measure isn't neverending then test, if it whole fits into one or two DMA buffers
1095                 if (!devpriv->ai_neverending) {
1096                         // fits whole measure into one DMA buffer?
1097                         if (dmalen0 >
1098                                 ((devpriv->ai_n_realscanlen << 1) *
1099                                         devpriv->ai_scans)) {
1100                                 DPRINTK("3.0 ai_n_realscanlen=%d ai_scans=%d \n", devpriv->ai_n_realscanlen, devpriv->ai_scans);
1101                                 dmalen0 =
1102                                         (devpriv->ai_n_realscanlen << 1) *
1103                                         devpriv->ai_scans;
1104                                 DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0,
1105                                         dmalen1);
1106                                 dmalen0 &= ~3L;
1107                         } else {        // fits whole measure into two DMA buffer?
1108                                 if (dmalen1 >
1109                                         ((devpriv->ai_n_realscanlen << 1) *
1110                                                 devpriv->ai_scans - dmalen0))
1111                                         dmalen1 =
1112                                                 (devpriv->
1113                                                 ai_n_realscanlen << 1) *
1114                                                 devpriv->ai_scans - dmalen0;
1115                                 DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
1116                                         dmalen1);
1117                                 dmalen1 &= ~3L;
1118                         }
1119                 }
1120         }
1121
1122         DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1123
1124         // these DMA buffer size we'll be used
1125         devpriv->dma_actbuf = 0;
1126         devpriv->dmabuf_use_size[0] = dmalen0;
1127         devpriv->dmabuf_use_size[1] = dmalen1;
1128
1129         DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1130 #if 0
1131         if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1132                 devpriv->dmabuf_panic_size[0] =
1133                         (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1134                         1) * devpriv->ai_n_scanlen * sizeof(short);
1135                 devpriv->dmabuf_panic_size[1] =
1136                         (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1137                         1) * devpriv->ai_n_scanlen * sizeof(short);
1138         } else {
1139                 devpriv->dmabuf_panic_size[0] =
1140                         (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1141                 devpriv->dmabuf_panic_size[1] =
1142                         (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1143         }
1144 #endif
1145
1146         outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR);    // stop DMA
1147         outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1148         outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1149         // init DMA transfer
1150         outl(0x00000000 | AINT_WRITE_COMPL,
1151                 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1152 //      outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);
1153
1154         outl(inl(devpriv->iobase_a +
1155                         AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1156                 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1157         outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_INTCSR);   // allow bus mastering
1158
1159         DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
1160         return 0;
1161 }
1162
1163 /*
1164 ==============================================================================
1165 */
1166 static int pci9118_ai_docmd_sampl(struct comedi_device * dev, struct comedi_subdevice * s)
1167 {
1168         DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
1169                 dev->minor, devpriv->ai_do);
1170         switch (devpriv->ai_do) {
1171         case 1:
1172                 devpriv->AdControlReg |= AdControl_TmrTr;
1173                 break;
1174         case 2:
1175                 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1176                 return -EIO;
1177         case 3:
1178                 devpriv->AdControlReg |= AdControl_ExtM;
1179                 break;
1180         case 4:
1181                 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1182                 return -EIO;
1183         default:
1184                 comedi_error(dev,
1185                         "pci9118_ai_docmd_sampl() mode number bug!\n");
1186                 return -EIO;
1187         };
1188
1189         devpriv->int_ai_func = interrupt_pci9118_ai_onesample;  //transfer function
1190
1191         if (devpriv->ai12_startstop)
1192                 pci9118_exttrg_add(dev, EXTTRG_AI);     // activate EXT trigger
1193
1194         if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1195                 devpriv->IntControlReg |= Int_Timer;
1196
1197         devpriv->AdControlReg |= AdControl_Int;
1198
1199         outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR);     // allow INT in AMCC
1200
1201         if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1202                 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1203                 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1204                 if (devpriv->ai_do != 3) {
1205                         start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1206                                 devpriv->ai_divisor2);
1207                         devpriv->AdControlReg |= AdControl_SoftG;
1208                 }
1209                 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1210         }
1211
1212         DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
1213         return 0;
1214 }
1215
1216 /*
1217 ==============================================================================
1218 */
1219 static int pci9118_ai_docmd_dma(struct comedi_device * dev, struct comedi_subdevice * s)
1220 {
1221         DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
1222                 dev->minor, devpriv->ai_do, devpriv->usedma);
1223         Compute_and_setup_dma(dev);
1224
1225         switch (devpriv->ai_do) {
1226         case 1:
1227                 devpriv->AdControlReg |=
1228                         ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1229                 break;
1230         case 2:
1231                 devpriv->AdControlReg |=
1232                         ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1233                 devpriv->AdFunctionReg =
1234                         AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1235                         AdFunction_BS;
1236                 if (devpriv->usessh && (!devpriv->softsshdelay))
1237                         devpriv->AdFunctionReg |= AdFunction_BSSH;
1238                 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1239                 break;
1240         case 3:
1241                 devpriv->AdControlReg |=
1242                         ((AdControl_ExtM | AdControl_Dma) & 0xff);
1243                 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1244                 break;
1245         case 4:
1246                 devpriv->AdControlReg |=
1247                         ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1248                 devpriv->AdFunctionReg =
1249                         AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1250                 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1251                 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1252                 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1253                         dev->iobase + PCI9118_CNT0);
1254                 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1255                         dev->iobase + PCI9118_CNT0);
1256                 devpriv->AdFunctionReg |= AdFunction_Start;
1257                 break;
1258         default:
1259                 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1260                 return -EIO;
1261         };
1262
1263         if (devpriv->ai12_startstop) {
1264                 pci9118_exttrg_add(dev, EXTTRG_AI);     // activate EXT trigger
1265         }
1266
1267         devpriv->int_ai_func = interrupt_pci9118_ai_dma;        //transfer function
1268
1269         outl(0x02000000 | AINT_WRITE_COMPL,
1270                 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1271
1272         if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1273                 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1274                 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1275                 if (devpriv->ai_do != 3) {
1276                         start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1277                                 devpriv->ai_divisor2);
1278                         devpriv->AdControlReg |= AdControl_SoftG;
1279                 }
1280                 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1281         }
1282
1283         DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
1284         return 0;
1285 }
1286
1287 /*
1288 ==============================================================================
1289 */
1290 static int pci9118_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
1291 {
1292         struct comedi_cmd *cmd = &s->async->cmd;
1293         unsigned int addchans = 0;
1294         int ret = 0;
1295
1296         DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
1297         devpriv->ai12_startstop = 0;
1298         devpriv->ai_flags = cmd->flags;
1299         devpriv->ai_n_chan = cmd->chanlist_len;
1300         devpriv->ai_n_scanlen = cmd->scan_end_arg;
1301         devpriv->ai_chanlist = cmd->chanlist;
1302         devpriv->ai_data = s->async->prealloc_buf;
1303         devpriv->ai_data_len = s->async->prealloc_bufsz;
1304         devpriv->ai_timer1 = 0;
1305         devpriv->ai_timer2 = 0;
1306         devpriv->ai_add_front = 0;
1307         devpriv->ai_add_back = 0;
1308         devpriv->ai_maskerr = 0x10e;
1309
1310         // prepare for start/stop conditions
1311         if (cmd->start_src == TRIG_EXT)
1312                 devpriv->ai12_startstop |= START_AI_EXT;
1313         if (cmd->stop_src == TRIG_EXT) {
1314                 devpriv->ai_neverending = 1;
1315                 devpriv->ai12_startstop |= STOP_AI_EXT;
1316         }
1317         if (cmd->start_src == TRIG_INT) {
1318                 devpriv->ai12_startstop |= START_AI_INT;
1319                 devpriv->ai_inttrig_start = cmd->start_arg;
1320                 s->async->inttrig = pci9118_ai_inttrig;
1321         }
1322 #if 0
1323         if (cmd->stop_src == TRIG_INT) {
1324                 devpriv->ai_neverending = 1;
1325                 devpriv->ai12_startstop |= STOP_AI_INT;
1326         }
1327 #endif
1328         if (cmd->stop_src == TRIG_NONE)
1329                 devpriv->ai_neverending = 1;
1330         if (cmd->stop_src == TRIG_COUNT) {
1331                 devpriv->ai_scans = cmd->stop_arg;
1332                 devpriv->ai_neverending = 0;
1333         } else {
1334                 devpriv->ai_scans = 0;
1335         }
1336
1337         // use sample&hold signal?
1338         if (cmd->convert_src == TRIG_NOW) {
1339                 devpriv->usessh = 1;
1340         }                       // yes
1341         else {
1342                 devpriv->usessh = 0;
1343         }                       // no
1344
1345         DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
1346                 devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
1347                 devpriv->ai12_startstop);
1348
1349         // use additional sample at end of every scan to satisty DMA 32 bit transfer?
1350         devpriv->ai_add_front = 0;
1351         devpriv->ai_add_back = 0;
1352         devpriv->useeoshandle = 0;
1353         if (devpriv->master) {
1354                 devpriv->usedma = 1;
1355                 if ((cmd->flags & TRIG_WAKE_EOS) &&
1356                         (devpriv->ai_n_scanlen == 1)) {
1357                         if (cmd->convert_src == TRIG_NOW) {
1358                                 devpriv->ai_add_back = 1;
1359                         }
1360                         if (cmd->convert_src == TRIG_TIMER) {
1361                                 devpriv->usedma = 0;    // use INT transfer if scanlist have only one channel
1362                         }
1363                 }
1364                 if ((cmd->flags & TRIG_WAKE_EOS) &&
1365                         (devpriv->ai_n_scanlen & 1) &&
1366                         (devpriv->ai_n_scanlen > 1)) {
1367                         if (cmd->scan_begin_src == TRIG_FOLLOW) {
1368                                 //vpriv->useeoshandle=1; // change DMA transfer block to fit EOS on every second call
1369                                 devpriv->usedma = 0;    // XXX maybe can be corrected to use 16 bit DMA
1370                         } else {        // well, we must insert one sample to end of EOS to meet 32 bit transfer
1371                                 devpriv->ai_add_back = 1;
1372                         }
1373                 }
1374         } else {                // interrupt transfer don't need any correction
1375                 devpriv->usedma = 0;
1376         }
1377
1378         // we need software S&H signal? It add  two samples before every scan as minimum
1379         if (devpriv->usessh && devpriv->softsshdelay) {
1380                 devpriv->ai_add_front = 2;
1381                 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {    // move it to front
1382                         devpriv->ai_add_front++;
1383                         devpriv->ai_add_back = 0;
1384                 }
1385                 if (cmd->convert_arg < this_board->ai_ns_min)
1386                         cmd->convert_arg = this_board->ai_ns_min;
1387                 addchans = devpriv->softsshdelay / cmd->convert_arg;
1388                 if (devpriv->softsshdelay % cmd->convert_arg)
1389                         addchans++;
1390                 if (addchans > (devpriv->ai_add_front - 1)) {   // uff, still short :-(
1391                         devpriv->ai_add_front = addchans + 1;
1392                         if (devpriv->usedma == 1)
1393                                 if ((devpriv->ai_add_front +
1394                                                 devpriv->ai_n_chan +
1395                                                 devpriv->ai_add_back) & 1)
1396                                         devpriv->ai_add_front++;        // round up to 32 bit
1397                 }
1398         }                       // well, we now know what must be all added
1399
1400         devpriv->ai_n_realscanlen =     // what we must take from card in real to have ai_n_scanlen on output?
1401                 (devpriv->ai_add_front + devpriv->ai_n_chan +
1402                 devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1403                 devpriv->ai_n_chan);
1404
1405         DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1406                 devpriv->usedma,
1407                 devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1408                 devpriv->ai_n_chan, devpriv->ai_add_back,
1409                 devpriv->ai_n_scanlen);
1410
1411         // check and setup channel list
1412         if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1413                         devpriv->ai_chanlist, devpriv->ai_add_front,
1414                         devpriv->ai_add_back))
1415                 return -EINVAL;
1416         if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1417                         devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1418                         devpriv->ai_add_back, devpriv->usedma,
1419                         devpriv->useeoshandle))
1420                 return -EINVAL;
1421
1422         // compute timers settings
1423         // simplest way, fr=4Mhz/(tim1*tim2), channel manipulation without timers effect
1424         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
1425                 if (cmd->scan_begin_src == TRIG_EXT) {
1426                         devpriv->ai_do = 4;
1427                 } else {
1428                         devpriv->ai_do = 1;
1429                 }
1430                 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1431                         &cmd->scan_begin_arg, &cmd->convert_arg,
1432                         devpriv->ai_flags, devpriv->ai_n_realscanlen,
1433                         &devpriv->ai_divisor1, &devpriv->ai_divisor2,
1434                         devpriv->usessh, devpriv->ai_add_front);
1435                 devpriv->ai_timer2 = cmd->convert_arg;
1436         }
1437
1438         if ((cmd->scan_begin_src == TRIG_TIMER) && ((cmd->convert_src == TRIG_TIMER) || (cmd->convert_src == TRIG_NOW))) {      // double timed action
1439                 if (!devpriv->usedma) {
1440                         comedi_error(dev,
1441                                 "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!");
1442                         return -EIO;
1443                 }
1444
1445                 devpriv->ai_do = 2;
1446                 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1447                         &cmd->scan_begin_arg, &cmd->convert_arg,
1448                         devpriv->ai_flags, devpriv->ai_n_realscanlen,
1449                         &devpriv->ai_divisor1, &devpriv->ai_divisor2,
1450                         devpriv->usessh, devpriv->ai_add_front);
1451                 devpriv->ai_timer1 = cmd->scan_begin_arg;
1452                 devpriv->ai_timer2 = cmd->convert_arg;
1453         }
1454
1455         if ((cmd->scan_begin_src == TRIG_FOLLOW)
1456                 && (cmd->convert_src == TRIG_EXT)) {
1457                 devpriv->ai_do = 3;
1458         }
1459
1460         start_pacer(dev, -1, 0, 0);     // stop pacer
1461
1462         devpriv->AdControlReg = 0;      // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable DMA
1463         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1464         devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;   // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
1465         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1466         comedi_udelay(1);
1467         outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
1468         inl(dev->iobase + PCI9118_ADSTAT);      // flush A/D and INT status register
1469         inl(dev->iobase + PCI9118_INTSRC);
1470
1471         devpriv->ai_act_scan = 0;
1472         devpriv->ai_act_dmapos = 0;
1473         s->async->cur_chan = 0;
1474         devpriv->ai_buf_ptr = 0;
1475
1476         if (devpriv->usedma) {
1477                 ret = pci9118_ai_docmd_dma(dev, s);
1478         } else {
1479                 ret = pci9118_ai_docmd_sampl(dev, s);
1480         }
1481
1482         DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1483         return ret;
1484 }
1485
1486 /*
1487 ==============================================================================
1488 */
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)
1491 {
1492         unsigned int i, differencial = 0, bipolar = 0;
1493
1494         /* correct channel and range number check itself comedi/range.c */
1495         if (n_chan < 1) {
1496                 comedi_error(dev, "range/channel list is empty!");
1497                 return 0;
1498         }
1499         if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1500                 rt_printk
1501                         ("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
1502                         dev->minor, n_chan,
1503                         s->len_chanlist - frontadd - backadd);
1504                 return 0;
1505         }
1506
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
1511         if (n_chan > 1)
1512                 for (i = 1; i < n_chan; i++) {  // check S.E/diff
1513                         if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1514                                 (differencial)) {
1515                                 comedi_error(dev,
1516                                         "Differencial and single ended inputs cann't be mixtured!");
1517                                 return 0;
1518                         }
1519                         if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1520                                 (bipolar)) {
1521                                 comedi_error(dev,
1522                                         "Bipolar and unipolar ranges cann't be mixtured!");
1523                                 return 0;
1524                         }
1525                         if ((!devpriv->usemux) & (differencial) &
1526                                 (CR_CHAN(chanlist[i]) >=
1527                                         this_board->n_aichand)) {
1528                                 comedi_error(dev,
1529                                         "If AREF_DIFF is used then is available only first 8 channels!");
1530                                 return 0;
1531                         }
1532                 }
1533
1534         return 1;
1535 }
1536
1537 /*
1538 ==============================================================================
1539 */
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)
1543 {
1544         unsigned int i, differencial = 0, bipolar = 0;
1545         unsigned int scanquad, gain, ssh = 0x00;
1546
1547         DPRINTK("adl_pci9118 EDBG: BGN: setup_channel_list(%d,.,%d,.,%d,%d,%d,%d)\n", dev->minor, n_chan, rot, frontadd, backadd, usedma);
1548
1549         if (usedma == 1) {
1550                 rot = 8;
1551                 usedma = 0;
1552         }
1553
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
1558
1559         // All is ok, so we can setup channel/range list
1560
1561         if (!bipolar) {
1562                 devpriv->AdControlReg |= AdControl_UniP;        // set unibipolar
1563         } else {
1564                 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);    // enable bipolar
1565         }
1566
1567         if (differencial) {
1568                 devpriv->AdControlReg |= AdControl_Diff;        // enable diff inputs
1569         } else {
1570                 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);    // set single ended inputs
1571         }
1572
1573         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);     // setup mode
1574
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);
1578
1579 #ifdef PCI9118_PARANOIDCHECK
1580         devpriv->chanlistlen = n_chan;
1581         for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1582                 devpriv->chanlist[i] = 0x55aa;
1583 #endif
1584
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;
1595                 }
1596                 DPRINTK("\n ");
1597         }
1598
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;
1604 #endif
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);
1609         }
1610         DPRINTK("\n ");
1611
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);
1620                 }
1621                 DPRINTK("\n ");
1622         }
1623 #ifdef PCI9118_PARANOIDCHECK
1624         devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];     // for 32bit oerations
1625         if (useeos) {
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;
1629                 }
1630                 devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma];       // for 32bit oerations
1631                 useeos = 2;
1632         } else {
1633                 useeos = 1;
1634         }
1635 #ifdef PCI9118_EXTDEBUG
1636         DPRINTK("CHL: ");
1637         for (i = 0; i <= (useeos * n_chan); i++) {
1638                 DPRINTK("%04x ", devpriv->chanlist[i]);
1639         }
1640         DPRINTK("\n ");
1641 #endif
1642 #endif
1643         outl(0, dev->iobase + PCI9118_SCANMOD); // close scan queue
1644 //      comedi_udelay(100);                             // important delay, or first sample will be cripled
1645
1646         DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1647         return 1;               // we can serve this with scan logic
1648 }
1649
1650 /*
1651 ==============================================================================
1652   calculate 8254 divisors if they are used for dual timing
1653 */
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)
1658 {
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);
1660         switch (mode) {
1661         case 1:
1662         case 4:
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);
1669                 break;
1670         case 2:
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,
1674                         *tim1, *tim2);
1675                 *div1 = *tim2 / devpriv->i8254_osc_base;        // convert timer (burst)
1676                 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1677                         *tim1, *tim2);
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,
1681                         *tim1, *tim2);
1682                 *div2 = *tim1 / devpriv->i8254_osc_base;        // scan timer
1683                 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1684                         *tim1, *tim2);
1685                 *div2 = *div2 / *div1;  // major timer is c1*c2
1686                 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1687                         *tim1, *tim2);
1688                 if (*div2 < chans)
1689                         *div2 = chans;
1690                 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1691                         *tim1, *tim2);
1692
1693                 *tim2 = *div1 * devpriv->i8254_osc_base;        // real convert timer
1694
1695                 if (usessh & (chnsshfront == 0))        // use BSSH signal
1696                         if (*div2 < (chans + 2))
1697                                 *div2 = chans + 2;
1698
1699                 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1700                         *tim1, *tim2);
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);
1704                 break;
1705         }
1706         DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
1707                 *div1, *div2);
1708 }
1709
1710 /*
1711 ==============================================================================
1712 */
1713 static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
1714         unsigned int divisor2)
1715 {
1716         outl(0x74, dev->iobase + PCI9118_CNTCTRL);
1717         outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
1718 //      outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1719         comedi_udelay(1);
1720
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);
1726         }
1727 }
1728
1729 /*
1730 ==============================================================================
1731 */
1732 static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source)
1733 {
1734         if (source > 3)
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
1740         return 0;
1741 }
1742
1743 /*
1744 ==============================================================================
1745 */
1746 static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source)
1747 {
1748         if (source > 3)
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);
1756         }
1757         return 0;
1758 }
1759
1760 /*
1761 ==============================================================================
1762 */
1763 static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
1764 {
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
1777
1778         devpriv->ai_do = 0;
1779         devpriv->usedma = 0;
1780
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;
1788
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
1791
1792         return 0;
1793 }
1794
1795 /*
1796 ==============================================================================
1797 */
1798 static int pci9118_reset(struct comedi_device * dev)
1799 {
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
1814
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
1820         comedi_udelay(10);
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
1828
1829         devpriv->cnt0_users = 0;
1830         devpriv->exttrg_users = 0;
1831
1832         return 0;
1833 }
1834
1835 /*
1836 ==============================================================================
1837 */
1838 static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it)
1839 {
1840         struct comedi_subdevice *s;
1841         int ret, pages, i;
1842         unsigned short master;
1843         unsigned int irq;
1844         unsigned long iobase_a, iobase_9;
1845         struct pci_dev *pcidev;
1846         int opt_bus, opt_slot;
1847         const char *errstr;
1848         unsigned char pci_bus, pci_slot, pci_func;
1849         u16 u16w;
1850
1851         rt_printk("comedi%d: adl_pci9118: board=%s", dev->minor,
1852                 this_board->name);
1853
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
1858         } else {
1859                 master = 1;
1860         }
1861
1862         if ((ret = alloc_private(dev, sizeof(struct pci9118_private))) < 0) {
1863                 rt_printk(" - Allocation failed!\n");
1864                 return -ENOMEM;
1865         }
1866
1867         /* Look for matching PCI device */
1868         errstr = "not found!";
1869         pcidev = NULL;
1870         while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
1871                                 this_board->device_id, pcidev))) {
1872                 /* Found matching vendor/device. */
1873                 if (opt_bus || opt_slot) {
1874                         /* Check bus/slot. */
1875                         if (opt_bus != pcidev->bus->number
1876                                 || opt_slot != PCI_SLOT(pcidev->devfn))
1877                                 continue;       /* no match */
1878                 }
1879                 /*
1880                  * Look for device that isn't in use.
1881                  * Enable PCI device and request regions.
1882                  */
1883                 if (comedi_pci_enable(pcidev, "adl_pci9118")) {
1884                         errstr = "failed to enable PCI device and request regions!";
1885                         continue;
1886                 }
1887                 break;
1888         }
1889
1890         if (!pcidev) {
1891                 if (opt_bus || opt_slot) {
1892                         rt_printk(" - Card at b:s %d:%d %s\n",
1893                                 opt_bus, opt_slot, errstr);
1894                 } else {
1895                         rt_printk(" - Card %s\n", errstr);
1896                 }
1897                 return -EIO;
1898         }
1899
1900         if (master) {
1901                 pci_set_master(pcidev);
1902         }
1903
1904         pci_bus = pcidev->bus->number;
1905         pci_slot = PCI_SLOT(pcidev->devfn);
1906         pci_func = PCI_FUNC(pcidev->devfn);
1907         irq = pcidev->irq;
1908         iobase_a = pci_resource_start(pcidev, 0);
1909         iobase_9 = pci_resource_start(pcidev, 2);
1910
1911         rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot,
1912                 pci_func, iobase_9, iobase_a);
1913
1914         dev->iobase = iobase_9;
1915         dev->board_name = this_board->name;
1916
1917         devpriv->pcidev = pcidev;
1918         devpriv->iobase_a = iobase_a;
1919
1920         pci9118_reset(dev);
1921
1922         if (it->options[3] & 2)
1923                 irq = 0;        // user don't want use IRQ
1924         if (irq > 0) {
1925                 if (comedi_request_irq(irq, interrupt_pci9118, IRQF_SHARED,
1926                                 "ADLink PCI-9118", dev)) {
1927                         rt_printk(", unable to allocate IRQ %d, DISABLING IT",
1928                                 irq);
1929                         irq = 0;        /* Can't use IRQ */
1930                 } else {
1931                         rt_printk(", irq=%u", irq);
1932                 }
1933         } else {
1934                 rt_printk(", IRQ disabled");
1935         }
1936
1937         dev->irq = irq;
1938
1939         if (master) {           // alloc DMA buffers
1940                 devpriv->dma_doublebuf = 0;
1941                 for (i = 0; i < 2; i++) {
1942                         for (pages = 4; pages >= 0; pages--)
1943                                 if ((devpriv->dmabuf_virt[i] = (short *)
1944                                                 __get_free_pages(GFP_KERNEL,
1945                                                         pages)))
1946                                         break;
1947                         if (devpriv->dmabuf_virt[i]) {
1948                                 devpriv->dmabuf_pages[i] = pages;
1949                                 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
1950                                 devpriv->dmabuf_samples[i] =
1951                                         devpriv->dmabuf_size[i] >> 1;
1952                                 devpriv->dmabuf_hw[i] =
1953                                         virt_to_bus((void *)devpriv->
1954                                         dmabuf_virt[i]);
1955                         }
1956                 }
1957                 if (!devpriv->dmabuf_virt[0]) {
1958                         rt_printk(", Can't allocate DMA buffer, DMA disabled!");
1959                         master = 0;
1960                 }
1961
1962                 if (devpriv->dmabuf_virt[1])
1963                         devpriv->dma_doublebuf = 1;
1964
1965         }
1966
1967         if ((devpriv->master = master)) {
1968                 rt_printk(", bus master");
1969         } else {
1970                 rt_printk(", no bus master");
1971         }
1972
1973         devpriv->usemux = 0;
1974         if (it->options[2] > 0) {
1975                 devpriv->usemux = it->options[2];
1976                 if (devpriv->usemux > 256)
1977                         devpriv->usemux = 256;  // max 256 channels!
1978                 if (it->options[4] > 0)
1979                         if (devpriv->usemux > 128) {
1980                                 devpriv->usemux = 128;  // max 128 channels with softare S&H!
1981                         }
1982                 rt_printk(", ext. mux %d channels", devpriv->usemux);
1983         }
1984
1985         devpriv->softsshdelay = it->options[4];
1986         if (devpriv->softsshdelay < 0) {        // select sample&hold signal polarity
1987                 devpriv->softsshdelay = -devpriv->softsshdelay;
1988                 devpriv->softsshsample = 0x80;
1989                 devpriv->softsshhold = 0x00;
1990         } else {
1991                 devpriv->softsshsample = 0x00;
1992                 devpriv->softsshhold = 0x80;
1993         }
1994
1995         rt_printk(".\n");
1996
1997         pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
1998         pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); // Enable parity check for parity error
1999
2000         if ((ret = alloc_subdevices(dev, 4)) < 0)
2001                 return ret;
2002
2003         s = dev->subdevices + 0;
2004         dev->read_subdev = s;
2005         s->type = COMEDI_SUBD_AI;
2006         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2007         if (devpriv->usemux) {
2008                 s->n_chan = devpriv->usemux;
2009         } else {
2010                 s->n_chan = this_board->n_aichan;
2011         }
2012         s->maxdata = this_board->ai_maxdata;
2013         s->len_chanlist = this_board->n_aichanlist;
2014         s->range_table = this_board->rangelist_ai;
2015         s->cancel = pci9118_ai_cancel;
2016         s->insn_read = pci9118_insn_read_ai;
2017         if (dev->irq) {
2018                 s->subdev_flags |= SDF_CMD_READ;
2019                 s->do_cmdtest = pci9118_ai_cmdtest;
2020                 s->do_cmd = pci9118_ai_cmd;
2021                 s->munge = pci9118_ai_munge;
2022         }
2023
2024         s = dev->subdevices + 1;
2025         s->type = COMEDI_SUBD_AO;
2026         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2027         s->n_chan = this_board->n_aochan;
2028         s->maxdata = this_board->ao_maxdata;
2029         s->len_chanlist = this_board->n_aochan;
2030         s->range_table = this_board->rangelist_ao;
2031         s->insn_write = pci9118_insn_write_ao;
2032         s->insn_read = pci9118_insn_read_ao;
2033
2034         s = dev->subdevices + 2;
2035         s->type = COMEDI_SUBD_DI;
2036         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2037         s->n_chan = 4;
2038         s->maxdata = 1;
2039         s->len_chanlist = 4;
2040         s->range_table = &range_digital;
2041         s->io_bits = 0;         /* all bits input */
2042         s->insn_bits = pci9118_insn_bits_di;
2043
2044         s = dev->subdevices + 3;
2045         s->type = COMEDI_SUBD_DO;
2046         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2047         s->n_chan = 4;
2048         s->maxdata = 1;
2049         s->len_chanlist = 4;
2050         s->range_table = &range_digital;
2051         s->io_bits = 0xf;       /* all bits output */
2052         s->insn_bits = pci9118_insn_bits_do;
2053
2054         devpriv->valid = 1;
2055         devpriv->i8254_osc_base = 250;  // 250ns=4MHz
2056         devpriv->ai_maskharderr = 0x10a;        // default measure crash condition
2057         if (it->options[5])     // disable some requested
2058                 devpriv->ai_maskharderr &= ~it->options[5];
2059
2060         switch (this_board->ai_maxdata) {
2061         case 0xffff:
2062                 devpriv->ai16bits = 1;
2063                 break;
2064         default:
2065                 devpriv->ai16bits = 0;
2066                 break;
2067         }
2068         return 0;
2069 }
2070
2071 /*
2072 ==============================================================================
2073 */
2074 static int pci9118_detach(struct comedi_device * dev)
2075 {
2076         if (dev->private) {
2077                 if (devpriv->valid)
2078                         pci9118_reset(dev);
2079                 if (dev->irq)
2080                         comedi_free_irq(dev->irq, dev);
2081                 if (devpriv->pcidev) {
2082                         if (dev->iobase) {
2083                                 comedi_pci_disable(devpriv->pcidev);
2084                         }
2085                         pci_dev_put(devpriv->pcidev);
2086                 }
2087                 if (devpriv->dmabuf_virt[0])
2088                         free_pages((unsigned long)devpriv->dmabuf_virt[0],
2089                                 devpriv->dmabuf_pages[0]);
2090                 if (devpriv->dmabuf_virt[1])
2091                         free_pages((unsigned long)devpriv->dmabuf_virt[1],
2092                                 devpriv->dmabuf_pages[1]);
2093         }
2094
2095         return 0;
2096 }
2097
2098 /*
2099 ==============================================================================
2100 */