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