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