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