b0e39cb7477482418b46eec89030daeee59ca429
[pandora-kernel.git] / drivers / staging / comedi / drivers / adl_pci9118.c
1 /*
2  *  comedi/drivers/adl_pci9118.c
3  *
4  *  hardware driver for ADLink cards:
5  *   card:   PCI-9118DG, PCI-9118HG, PCI-9118HR
6  *   driver: pci9118dg,  pci9118hg,  pci9118hr
7  *
8  * Author: Michal Dobes <dobes@tesnet.cz>
9  *
10 */
11 /*
12 Driver: adl_pci9118
13 Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
14 Author: Michal Dobes <dobes@tesnet.cz>
15 Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
16   PCI-9118HR (pci9118hr)
17 Status: works
18
19 This driver supports AI, AO, DI and DO subdevices.
20 AI subdevice supports cmd and insn interface,
21 other subdevices support only insn interface.
22 For AI:
23 - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
24 - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
25 - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
26 - It is not neccessary to have cmd.scan_end_arg=cmd.chanlist_len but
27   cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
28 - If return value of cmdtest is 5 then you've bad channel list
29   (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
30   ranges).
31
32 There are some hardware limitations:
33 a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
34    ended inputs.
35 b) DMA transfers must have the length aligned to two samples (32 bit),
36    so there is some problems if cmd->chanlist_len is odd. This driver tries
37    bypass this with adding one sample to the end of the every scan and discard
38    it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
39    and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
40    with interrupt after every sample.
41 c) If isn't used DMA then you can use only mode where
42    cmd->scan_begin_src=TRIG_FOLLOW.
43
44 Configuration options:
45   [0] - PCI bus of device (optional)
46   [1] - PCI slot of device (optional)
47         If bus/slot is not specified, then first available PCI
48         card will be used.
49   [2] - 0= standard 8 DIFF/16 SE channels configuration
50         n = external multiplexer connected, 1 <= n <= 256
51   [3] - 0=autoselect DMA or EOC interrupts operation
52         1 = disable DMA mode
53         3 = disable DMA and INT, only insn interface will work
54   [4] - sample&hold signal - card can generate signal for external S&H board
55         0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
56         0 != use ADCHN7(pin 23) signal is generated from driver, number 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
71 #include "amcc_s5933.h"
72 #include "8253.h"
73 #include "comedi_pci.h"
74 #include "comedi_fc.h"
75
76 #define PCI_VENDOR_ID_AMCC      0x10e8
77
78 /* paranoid checks are broken */
79 #undef PCI9118_PARANOIDCHECK    /*
80                                  * if defined, then is used code which control
81                                  * correct channel number on every 12 bit sample
82                                  */
83
84 #undef PCI9118_EXTDEBUG         /*
85                                  * if defined then driver prints
86                                  * a lot of messages
87                                  */
88
89 #undef DPRINTK
90 #ifdef PCI9118_EXTDEBUG
91 #define DPRINTK(fmt, args...) printk(fmt, ## args)
92 #else
93 #define DPRINTK(fmt, args...)
94 #endif
95
96 #define IORANGE_9118    64      /* I hope */
97 #define PCI9118_CHANLEN 255     /*
98                                  * len of chanlist, some source say 256,
99                                  * but reality looks like 255 :-(
100                                  */
101
102 #define PCI9118_CNT0    0x00    /* R/W: 8254 counter 0 */
103 #define PCI9118_CNT1    0x04    /* R/W: 8254 counter 0 */
104 #define PCI9118_CNT2    0x08    /* R/W: 8254 counter 0 */
105 #define PCI9118_CNTCTRL 0x0c    /* W:   8254 counter control */
106 #define PCI9118_AD_DATA 0x10    /* R:   A/D data */
107 #define PCI9118_DA1     0x10    /* W:   D/A registers */
108 #define PCI9118_DA2     0x14
109 #define PCI9118_ADSTAT  0x18    /* R:   A/D status register */
110 #define PCI9118_ADCNTRL 0x18    /* W:   A/D control register */
111 #define PCI9118_DI      0x1c    /* R:   digi input register */
112 #define PCI9118_DO      0x1c    /* W:   digi output register */
113 #define PCI9118_SOFTTRG 0x20    /* W:   soft trigger for A/D */
114 #define PCI9118_GAIN    0x24    /* W:   A/D gain/channel register */
115 #define PCI9118_BURST   0x28    /* W:   A/D burst number register */
116 #define PCI9118_SCANMOD 0x2c    /* W:   A/D auto scan mode */
117 #define PCI9118_ADFUNC  0x30    /* W:   A/D function register */
118 #define PCI9118_DELFIFO 0x34    /* W:   A/D data FIFO reset */
119 #define PCI9118_INTSRC  0x38    /* R:   interrupt reason register */
120 #define PCI9118_INTCTRL 0x38    /* W:   interrupt control register */
121
122 /* bits from A/D control register (PCI9118_ADCNTRL) */
123 #define AdControl_UniP  0x80    /* 1=bipolar, 0=unipolar */
124 #define AdControl_Diff  0x40    /* 1=differential, 0= single end inputs */
125 #define AdControl_SoftG 0x20    /* 1=8254 counter works, 0=counter stops */
126 #define AdControl_ExtG  0x10    /*
127                                  * 1=8254 countrol controlled by TGIN(pin 46),
128                                  * 0=controlled by SoftG
129                                  */
130 #define AdControl_ExtM  0x08    /*
131                                  * 1=external hardware trigger (pin 44),
132                                  * 0=internal trigger
133                                  */
134 #define AdControl_TmrTr 0x04    /*
135                                  * 1=8254 is iternal trigger source,
136                                  * 0=software trigger is source
137                                  * (register PCI9118_SOFTTRG)
138                                  */
139 #define AdControl_Int   0x02    /* 1=enable INT, 0=disable */
140 #define AdControl_Dma   0x01    /* 1=enable DMA, 0=disable */
141
142 /* bits from A/D function register (PCI9118_ADFUNC) */
143 #define AdFunction_PDTrg        0x80    /*
144                                          * 1=positive,
145                                          * 0=negative digital trigger
146                                          * (only positive is correct)
147                                          */
148 #define AdFunction_PETrg        0x40    /*
149                                          * 1=positive,
150                                          * 0=negative external trigger
151                                          * (only positive is correct)
152                                          */
153 #define AdFunction_BSSH         0x20    /* 1=with sample&hold, 0=without */
154 #define AdFunction_BM           0x10    /* 1=burst mode, 0=normal mode */
155 #define AdFunction_BS           0x08    /*
156                                          * 1=burst mode start,
157                                          * 0=burst mode stop
158                                          */
159 #define AdFunction_PM           0x04    /*
160                                          * 1=post trigger mode,
161                                          * 0=not post trigger
162                                          */
163 #define AdFunction_AM           0x02    /*
164                                          * 1=about trigger mode,
165                                          * 0=not about trigger
166                                          */
167 #define AdFunction_Start        0x01    /* 1=trigger start, 0=trigger stop */
168
169 /* bits from A/D status register (PCI9118_ADSTAT) */
170 #define AdStatus_nFull  0x100   /* 0=FIFO full (fatal), 1=not full */
171 #define AdStatus_nHfull 0x080   /* 0=FIFO half full, 1=FIFO not half full */
172 #define AdStatus_nEpty  0x040   /* 0=FIFO empty, 1=FIFO not empty */
173 #define AdStatus_Acmp   0x020   /*  */
174 #define AdStatus_DTH    0x010   /* 1=external digital trigger */
175 #define AdStatus_Bover  0x008   /* 1=burst mode overrun (fatal) */
176 #define AdStatus_ADOS   0x004   /* 1=A/D over speed (warning) */
177 #define AdStatus_ADOR   0x002   /* 1=A/D overrun (fatal) */
178 #define AdStatus_ADrdy  0x001   /* 1=A/D already ready, 0=not ready */
179
180 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
181 /* 1=interrupt occur, enable source,  0=interrupt not occur, disable source */
182 #define Int_Timer       0x08    /* timer interrupt */
183 #define Int_About       0x04    /* about trigger complete */
184 #define Int_Hfull       0x02    /* A/D FIFO hlaf full */
185 #define Int_DTrg        0x01    /* external digital trigger */
186
187 #define START_AI_EXT    0x01    /* start measure on external trigger */
188 #define STOP_AI_EXT     0x02    /* stop measure on external trigger */
189 #define START_AI_INT    0x04    /* start measure on internal trigger */
190 #define STOP_AI_INT     0x08    /* stop measure on internal trigger */
191
192 #define EXTTRG_AI       0       /* ext trg is used by AI */
193
194 static const struct comedi_lrange range_pci9118dg_hr = { 8, {
195                                                              BIP_RANGE(5),
196                                                              BIP_RANGE(2.5),
197                                                              BIP_RANGE(1.25),
198                                                              BIP_RANGE(0.625),
199                                                              UNI_RANGE(10),
200                                                              UNI_RANGE(5),
201                                                              UNI_RANGE(2.5),
202                                                              UNI_RANGE(1.25)
203                                                              }
204 };
205
206 static const struct comedi_lrange range_pci9118hg = { 8, {
207                                                           BIP_RANGE(5),
208                                                           BIP_RANGE(0.5),
209                                                           BIP_RANGE(0.05),
210                                                           BIP_RANGE(0.005),
211                                                           UNI_RANGE(10),
212                                                           UNI_RANGE(1),
213                                                           UNI_RANGE(0.1),
214                                                           UNI_RANGE(0.01)
215                                                           }
216 };
217
218 #define PCI9118_BIPOLAR_RANGES  4       /*
219                                          * used for test on mixture
220                                          * of BIP/UNI ranges
221                                          */
222
223 static int pci9118_attach(struct comedi_device *dev,
224                           struct comedi_devconfig *it);
225 static int pci9118_detach(struct comedi_device *dev);
226
227 struct boardtype {
228         const char *name;               /* board name */
229         int vendor_id;                  /* PCI vendor a device ID of card */
230         int device_id;
231         int iorange_amcc;               /* iorange for own S5933 region */
232         int iorange_9118;               /* pass thru card region size */
233         int n_aichan;                   /* num of A/D chans */
234         int n_aichand;                  /* num of A/D chans in diff mode */
235         int mux_aichan;                 /*
236                                          * num of A/D chans with
237                                          * external multiplexor
238                                          */
239         int n_aichanlist;               /* len of chanlist */
240         int n_aochan;                   /* num of D/A chans */
241         int ai_maxdata;                 /* resolution of A/D */
242         int ao_maxdata;                 /* resolution of D/A */
243         const struct comedi_lrange *rangelist_ai;       /* rangelist for A/D */
244         const struct comedi_lrange *rangelist_ao;       /* rangelist for D/A */
245         unsigned int ai_ns_min;         /* max sample speed of card v ns */
246         unsigned int ai_pacer_min;      /*
247                                          * minimal pacer value
248                                          * (c1*c2 or c1 in burst)
249                                          */
250         int half_fifo_size;             /* size of FIFO/2 */
251
252 };
253
254 static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
255         {
256         PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
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 unsigned 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 transfered */
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 allign 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                         }
1604                         if (cmd->convert_src == TRIG_TIMER) {
1605                                 devpriv->usedma = 0;
1606                                         /*
1607                                          * use INT transfer if scanlist
1608                                          * have only one channel
1609                                          */
1610                         }
1611                 }
1612                 if ((cmd->flags & TRIG_WAKE_EOS) &&
1613                     (devpriv->ai_n_scanlen & 1) &&
1614                     (devpriv->ai_n_scanlen > 1)) {
1615                         if (cmd->scan_begin_src == TRIG_FOLLOW) {
1616                                 /*
1617                                  * vpriv->useeoshandle=1; // change DMA transfer
1618                                  * block to fit EOS on every second call
1619                                  */
1620                                 devpriv->usedma = 0;
1621                                 /*
1622                                  * XXX maybe can be corrected to use 16 bit DMA
1623                                  */
1624                         } else {        /*
1625                                          * well, we must insert one sample
1626                                          * to end of EOS to meet 32 bit transfer
1627                                          */
1628                                 devpriv->ai_add_back = 1;
1629                         }
1630                 }
1631         } else {        /* interrupt transfer don't need any correction */
1632                 devpriv->usedma = 0;
1633         }
1634
1635         /*
1636          * we need software S&H signal?
1637          * It adds two samples before every scan as minimum
1638          */
1639         if (devpriv->usessh && devpriv->softsshdelay) {
1640                 devpriv->ai_add_front = 2;
1641                 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1642                                                         /* move it to front */
1643                         devpriv->ai_add_front++;
1644                         devpriv->ai_add_back = 0;
1645                 }
1646                 if (cmd->convert_arg < this_board->ai_ns_min)
1647                         cmd->convert_arg = this_board->ai_ns_min;
1648                 addchans = devpriv->softsshdelay / cmd->convert_arg;
1649                 if (devpriv->softsshdelay % cmd->convert_arg)
1650                         addchans++;
1651                 if (addchans > (devpriv->ai_add_front - 1)) {
1652                                                         /* uff, still short */
1653                         devpriv->ai_add_front = addchans + 1;
1654                         if (devpriv->usedma == 1)
1655                                 if ((devpriv->ai_add_front +
1656                                      devpriv->ai_n_chan +
1657                                      devpriv->ai_add_back) & 1)
1658                                         devpriv->ai_add_front++;
1659                                                         /* round up to 32 bit */
1660                 }
1661         }
1662         /* well, we now know what must be all added */
1663         devpriv->ai_n_realscanlen =     /*
1664                                          * what we must take from card in real
1665                                          * to have ai_n_scanlen on output?
1666                                          */
1667             (devpriv->ai_add_front + devpriv->ai_n_chan +
1668              devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1669                                       devpriv->ai_n_chan);
1670
1671         DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1672                 devpriv->usedma,
1673                 devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1674                 devpriv->ai_n_chan, devpriv->ai_add_back,
1675                 devpriv->ai_n_scanlen);
1676
1677         /* check and setup channel list */
1678         if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1679                                 devpriv->ai_chanlist, devpriv->ai_add_front,
1680                                 devpriv->ai_add_back))
1681                 return -EINVAL;
1682         if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1683                                 devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1684                                 devpriv->ai_add_back, devpriv->usedma,
1685                                 devpriv->useeoshandle))
1686                 return -EINVAL;
1687
1688         /* compute timers settings */
1689         /*
1690          * simplest way, fr=4Mhz/(tim1*tim2),
1691          * channel manipulation without timers effect
1692          */
1693         if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1694                 (cmd->scan_begin_src == TRIG_EXT) ||
1695                 (cmd->scan_begin_src == TRIG_INT)) &&
1696                 (cmd->convert_src == TRIG_TIMER)) {
1697                                         /* both timer is used for one time */
1698                 if (cmd->scan_begin_src == TRIG_EXT) {
1699                         devpriv->ai_do = 4;
1700                 } else {
1701                         devpriv->ai_do = 1;
1702                 }
1703                 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1704                                       &cmd->scan_begin_arg, &cmd->convert_arg,
1705                                       devpriv->ai_flags,
1706                                       devpriv->ai_n_realscanlen,
1707                                       &devpriv->ai_divisor1,
1708                                       &devpriv->ai_divisor2, devpriv->usessh,
1709                                       devpriv->ai_add_front);
1710                 devpriv->ai_timer2 = cmd->convert_arg;
1711         }
1712
1713         if ((cmd->scan_begin_src == TRIG_TIMER) &&
1714                 ((cmd->convert_src == TRIG_TIMER) ||
1715                 (cmd->convert_src == TRIG_NOW))) {
1716                                                 /* double timed action */
1717                 if (!devpriv->usedma) {
1718                         comedi_error(dev,
1719                                      "cmd->scan_begin_src=TRIG_TIMER works "
1720                                                 "only with bus mastering!");
1721                         return -EIO;
1722                 }
1723
1724                 devpriv->ai_do = 2;
1725                 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1726                                       &cmd->scan_begin_arg, &cmd->convert_arg,
1727                                       devpriv->ai_flags,
1728                                       devpriv->ai_n_realscanlen,
1729                                       &devpriv->ai_divisor1,
1730                                       &devpriv->ai_divisor2, devpriv->usessh,
1731                                       devpriv->ai_add_front);
1732                 devpriv->ai_timer1 = cmd->scan_begin_arg;
1733                 devpriv->ai_timer2 = cmd->convert_arg;
1734         }
1735
1736         if ((cmd->scan_begin_src == TRIG_FOLLOW)
1737             && (cmd->convert_src == TRIG_EXT)) {
1738                 devpriv->ai_do = 3;
1739         }
1740
1741         start_pacer(dev, -1, 0, 0);     /* stop pacer */
1742
1743         devpriv->AdControlReg = 0;      /*
1744                                          * bipolar, S.E., use 8254, stop 8354,
1745                                          * internal trigger, soft trigger,
1746                                          * disable DMA
1747                                          */
1748         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1749         devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1750                                         /*
1751                                          * positive triggers, no S&H, no burst,
1752                                          * burst stop, no post trigger,
1753                                          * no about trigger, trigger stop
1754                                          */
1755         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1756         udelay(1);
1757         outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1758         inl(dev->iobase + PCI9118_ADSTAT);      /*
1759                                                  * flush A/D and INT
1760                                                  * status register
1761                                                  */
1762         inl(dev->iobase + PCI9118_INTSRC);
1763
1764         devpriv->ai_act_scan = 0;
1765         devpriv->ai_act_dmapos = 0;
1766         s->async->cur_chan = 0;
1767         devpriv->ai_buf_ptr = 0;
1768
1769         if (devpriv->usedma)
1770                 ret = pci9118_ai_docmd_dma(dev, s);
1771         else
1772                 ret = pci9118_ai_docmd_sampl(dev, s);
1773
1774         DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1775         return ret;
1776 }
1777
1778 /*
1779 ==============================================================================
1780 */
1781 static int check_channel_list(struct comedi_device *dev,
1782                               struct comedi_subdevice *s, int n_chan,
1783                               unsigned int *chanlist, int frontadd, int backadd)
1784 {
1785         unsigned int i, differencial = 0, bipolar = 0;
1786
1787         /* correct channel and range number check itself comedi/range.c */
1788         if (n_chan < 1) {
1789                 comedi_error(dev, "range/channel list is empty!");
1790                 return 0;
1791         }
1792         if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1793                 printk
1794                     ("comedi%d: range/channel list is too long for "
1795                                                 "actual configuration (%d>%d)!",
1796                      dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
1797                 return 0;
1798         }
1799
1800         if (CR_AREF(chanlist[0]) == AREF_DIFF)
1801                 differencial = 1;       /* all input must be diff */
1802         if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1803                 bipolar = 1;    /* all input must be bipolar */
1804         if (n_chan > 1)
1805                 for (i = 1; i < n_chan; i++) {  /* check S.E/diff */
1806                         if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1807                             (differencial)) {
1808                                 comedi_error(dev,
1809                                              "Differencial and single ended "
1810                                                 "inputs can't be mixtured!");
1811                                 return 0;
1812                         }
1813                         if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1814                             (bipolar)) {
1815                                 comedi_error(dev,
1816                                              "Bipolar and unipolar ranges "
1817                                                         "can't be mixtured!");
1818                                 return 0;
1819                         }
1820                         if ((!devpriv->usemux) & (differencial) &
1821                             (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
1822                                 comedi_error(dev,
1823                                              "If AREF_DIFF is used then is "
1824                                         "available only first 8 channels!");
1825                                 return 0;
1826                         }
1827                 }
1828
1829         return 1;
1830 }
1831
1832 /*
1833 ==============================================================================
1834 */
1835 static int setup_channel_list(struct comedi_device *dev,
1836                               struct comedi_subdevice *s, int n_chan,
1837                               unsigned int *chanlist, int rot, int frontadd,
1838                               int backadd, int usedma, char useeos)
1839 {
1840         unsigned int i, differencial = 0, bipolar = 0;
1841         unsigned int scanquad, gain, ssh = 0x00;
1842
1843         DPRINTK
1844             ("adl_pci9118 EDBG: BGN: setup_channel_list"
1845                                                 "(%d,.,%d,.,%d,%d,%d,%d)\n",
1846              dev->minor, n_chan, rot, frontadd, backadd, usedma);
1847
1848         if (usedma == 1) {
1849                 rot = 8;
1850                 usedma = 0;
1851         }
1852
1853         if (CR_AREF(chanlist[0]) == AREF_DIFF)
1854                 differencial = 1;       /* all input must be diff */
1855         if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1856                 bipolar = 1;    /* all input must be bipolar */
1857
1858         /* All is ok, so we can setup channel/range list */
1859
1860         if (!bipolar) {
1861                 devpriv->AdControlReg |= AdControl_UniP;
1862                                                         /* set unibipolar */
1863         } else {
1864                 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
1865                                                         /* enable bipolar */
1866         }
1867
1868         if (differencial) {
1869                 devpriv->AdControlReg |= AdControl_Diff;
1870                                                         /* enable diff inputs */
1871         } else {
1872                 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
1873                                                 /* set single ended inputs */
1874         }
1875
1876         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1877                                                                 /* setup mode */
1878
1879         outl(2, dev->iobase + PCI9118_SCANMOD);
1880                                         /* gods know why this sequence! */
1881         outl(0, dev->iobase + PCI9118_SCANMOD);
1882         outl(1, dev->iobase + PCI9118_SCANMOD);
1883
1884 #ifdef PCI9118_PARANOIDCHECK
1885         devpriv->chanlistlen = n_chan;
1886         for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1887                 devpriv->chanlist[i] = 0x55aa;
1888 #endif
1889
1890         if (frontadd) {         /* insert channels for S&H */
1891                 ssh = devpriv->softsshsample;
1892                 DPRINTK("FA: %04x: ", ssh);
1893                 for (i = 0; i < frontadd; i++) {
1894                                                 /* store range list to card */
1895                         scanquad = CR_CHAN(chanlist[0]);
1896                                                 /* get channel number; */
1897                         gain = CR_RANGE(chanlist[0]);
1898                                                 /* get gain number */
1899                         scanquad |= ((gain & 0x03) << 8);
1900                         outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1901                         DPRINTK("%02x ", scanquad | ssh);
1902                         ssh = devpriv->softsshhold;
1903                 }
1904                 DPRINTK("\n ");
1905         }
1906
1907         DPRINTK("SL: ", ssh);
1908         for (i = 0; i < n_chan; i++) {  /* store range list to card */
1909                 scanquad = CR_CHAN(chanlist[i]);        /* get channel number */
1910 #ifdef PCI9118_PARANOIDCHECK
1911                 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1912 #endif
1913                 gain = CR_RANGE(chanlist[i]);           /* get gain number */
1914                 scanquad |= ((gain & 0x03) << 8);
1915                 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1916                 DPRINTK("%02x ", scanquad | ssh);
1917         }
1918         DPRINTK("\n ");
1919
1920         if (backadd) {          /* insert channels for fit onto 32bit DMA */
1921                 DPRINTK("BA: %04x: ", ssh);
1922                 for (i = 0; i < backadd; i++) { /* store range list to card */
1923                         scanquad = CR_CHAN(chanlist[0]);
1924                                                         /* get channel number */
1925                         gain = CR_RANGE(chanlist[0]);   /* get gain number */
1926                         scanquad |= ((gain & 0x03) << 8);
1927                         outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1928                         DPRINTK("%02x ", scanquad | ssh);
1929                 }
1930                 DPRINTK("\n ");
1931         }
1932 #ifdef PCI9118_PARANOIDCHECK
1933         devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
1934                                                 /* for 32bit operations */
1935         if (useeos) {
1936                 for (i = 1; i < n_chan; i++) {  /* store range list to card */
1937                         devpriv->chanlist[(n_chan + i) ^ usedma] =
1938                             (CR_CHAN(chanlist[i]) & 0xf) << rot;
1939                 }
1940                 devpriv->chanlist[(2 * n_chan) ^ usedma] =
1941                                                 devpriv->chanlist[0 ^ usedma];
1942                                                 /* for 32bit operations */
1943                 useeos = 2;
1944         } else {
1945                 useeos = 1;
1946         }
1947 #ifdef PCI9118_EXTDEBUG
1948         DPRINTK("CHL: ");
1949         for (i = 0; i <= (useeos * n_chan); i++)
1950                 DPRINTK("%04x ", devpriv->chanlist[i]);
1951
1952         DPRINTK("\n ");
1953 #endif
1954 #endif
1955         outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
1956         /* udelay(100); important delay, or first sample will be crippled */
1957
1958         DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1959         return 1;               /* we can serve this with scan logic */
1960 }
1961
1962 /*
1963 ==============================================================================
1964   calculate 8254 divisors if they are used for dual timing
1965 */
1966 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1967                                   struct comedi_subdevice *s,
1968                                   unsigned int *tim1, unsigned int *tim2,
1969                                   unsigned int flags, int chans,
1970                                   unsigned int *div1, unsigned int *div2,
1971                                   char usessh, unsigned int chnsshfront)
1972 {
1973         DPRINTK
1974             ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors"
1975                                         "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
1976              mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1977         switch (mode) {
1978         case 1:
1979         case 4:
1980                 if (*tim2 < this_board->ai_ns_min)
1981                         *tim2 = this_board->ai_ns_min;
1982                 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1983                                           tim2, flags & TRIG_ROUND_NEAREST);
1984                 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1985                         devpriv->i8254_osc_base, *div1, *div2, *tim1);
1986                 break;
1987         case 2:
1988                 if (*tim2 < this_board->ai_ns_min)
1989                         *tim2 = this_board->ai_ns_min;
1990                 DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1991                         *tim1, *tim2);
1992                 *div1 = *tim2 / devpriv->i8254_osc_base;
1993                                                 /* convert timer (burst) */
1994                 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1995                         *tim1, *tim2);
1996                 if (*div1 < this_board->ai_pacer_min)
1997                         *div1 = this_board->ai_pacer_min;
1998                 DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1999                         *tim1, *tim2);
2000                 *div2 = *tim1 / devpriv->i8254_osc_base;        /* scan timer */
2001                 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2002                         *tim1, *tim2);
2003                 *div2 = *div2 / *div1;          /* major timer is c1*c2 */
2004                 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2005                         *tim1, *tim2);
2006                 if (*div2 < chans)
2007                         *div2 = chans;
2008                 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2009                         *tim1, *tim2);
2010
2011                 *tim2 = *div1 * devpriv->i8254_osc_base;
2012                                                         /* real convert timer */
2013
2014                 if (usessh & (chnsshfront == 0))        /* use BSSH signal */
2015                         if (*div2 < (chans + 2))
2016                                 *div2 = chans + 2;
2017
2018                 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2019                         *tim1, *tim2);
2020                 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
2021                 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
2022                         devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
2023                 break;
2024         }
2025         DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
2026                 *div1, *div2);
2027 }
2028
2029 /*
2030 ==============================================================================
2031 */
2032 static void start_pacer(struct comedi_device *dev, int mode,
2033                         unsigned int divisor1, unsigned int divisor2)
2034 {
2035         outl(0x74, dev->iobase + PCI9118_CNTCTRL);
2036         outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
2037 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
2038         udelay(1);
2039
2040         if ((mode == 1) || (mode == 2) || (mode == 4)) {
2041                 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
2042                 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
2043                 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
2044                 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
2045         }
2046 }
2047
2048 /*
2049 ==============================================================================
2050 */
2051 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
2052 {
2053         if (source > 3)
2054                 return -1;                              /* incorrect source */
2055         devpriv->exttrg_users |= (1 << source);
2056         devpriv->IntControlReg |= Int_DTrg;
2057         outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2058         outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2059                                         devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2060                                                         /* allow INT in AMCC */
2061         return 0;
2062 }
2063
2064 /*
2065 ==============================================================================
2066 */
2067 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
2068 {
2069         if (source > 3)
2070                 return -1;                      /* incorrect source */
2071         devpriv->exttrg_users &= ~(1 << source);
2072         if (!devpriv->exttrg_users) {   /* shutdown ext trg intterrupts */
2073                 devpriv->IntControlReg &= ~Int_DTrg;
2074                 if (!devpriv->IntControlReg)    /* all IRQ disabled */
2075                         outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
2076                                         (~0x00001f00),
2077                                         devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2078                                                 /* disable int in AMCC */
2079                 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2080         }
2081         return 0;
2082 }
2083
2084 /*
2085 ==============================================================================
2086 */
2087 static int pci9118_ai_cancel(struct comedi_device *dev,
2088                              struct comedi_subdevice *s)
2089 {
2090         if (devpriv->usedma)
2091                 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
2092                         (~EN_A2P_TRANSFERS),
2093                         devpriv->iobase_a + AMCC_OP_REG_MCSR);  /* stop DMA */
2094         pci9118_exttrg_del(dev, EXTTRG_AI);
2095         start_pacer(dev, 0, 0, 0);      /* stop 8254 counters */
2096         devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2097         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2098                                         /*
2099                                          * positive triggers, no S&H, no burst,
2100                                          * burst stop, no post trigger,
2101                                          * no about trigger, trigger stop
2102                                          */
2103         devpriv->AdControlReg = 0x00;
2104         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2105                                         /*
2106                                          * bipolar, S.E., use 8254, stop 8354,
2107                                          * internal trigger, soft trigger,
2108                                          * disable INT and DMA
2109                                          */
2110         outl(0, dev->iobase + PCI9118_BURST);
2111         outl(1, dev->iobase + PCI9118_SCANMOD);
2112         outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
2113         outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
2114
2115         devpriv->ai_do = 0;
2116         devpriv->usedma = 0;
2117
2118         devpriv->ai_act_scan = 0;
2119         devpriv->ai_act_dmapos = 0;
2120         s->async->cur_chan = 0;
2121         s->async->inttrig = NULL;
2122         devpriv->ai_buf_ptr = 0;
2123         devpriv->ai_neverending = 0;
2124         devpriv->dma_actbuf = 0;
2125
2126         if (!devpriv->IntControlReg)
2127                 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2128                                         devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2129                                                         /* allow INT in AMCC */
2130
2131         return 0;
2132 }
2133
2134 /*
2135 ==============================================================================
2136 */
2137 static int pci9118_reset(struct comedi_device *dev)
2138 {
2139         devpriv->IntControlReg = 0;
2140         devpriv->exttrg_users = 0;
2141         inl(dev->iobase + PCI9118_INTCTRL);
2142         outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2143                                                 /* disable interrupts source */
2144         outl(0x30, dev->iobase + PCI9118_CNTCTRL);
2145 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
2146         start_pacer(dev, 0, 0, 0);              /* stop 8254 counters */
2147         devpriv->AdControlReg = 0;
2148         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2149                                                 /*
2150                                                  * bipolar, S.E., use 8254,
2151                                                  * stop 8354, internal trigger,
2152                                                  * soft trigger,
2153                                                  * disable INT and DMA
2154                                                  */
2155         outl(0, dev->iobase + PCI9118_BURST);
2156         outl(1, dev->iobase + PCI9118_SCANMOD);
2157         outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
2158         devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2159         outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2160                                                 /*
2161                                                  * positive triggers, no S&H,
2162                                                  * no burst, burst stop,
2163                                                  * no post trigger,
2164                                                  * no about trigger,
2165                                                  * trigger stop
2166                                                  */
2167
2168         devpriv->ao_data[0] = 2047;
2169         devpriv->ao_data[1] = 2047;
2170         outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
2171                                                 /* reset A/D outs to 0V */
2172         outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
2173         outl(0, dev->iobase + PCI9118_DO);      /* reset digi outs to L */
2174         udelay(10);
2175         inl(dev->iobase + PCI9118_AD_DATA);
2176         outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
2177         outl(0, dev->iobase + PCI9118_INTSRC);  /* remove INT requests */
2178         inl(dev->iobase + PCI9118_ADSTAT);      /* flush A/D status register */
2179         inl(dev->iobase + PCI9118_INTSRC);      /* flush INT requests */
2180         devpriv->AdControlReg = 0;
2181         outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2182                                                 /*
2183                                                  * bipolar, S.E., use 8254,
2184                                                  * stop 8354, internal trigger,
2185                                                  * soft trigger,
2186                                                  * disable INT and DMA
2187                                                  */
2188
2189         devpriv->cnt0_users = 0;
2190         devpriv->exttrg_users = 0;
2191
2192         return 0;
2193 }
2194
2195 /*
2196 ==============================================================================
2197 */
2198 static int pci9118_attach(struct comedi_device *dev,
2199                           struct comedi_devconfig *it)
2200 {
2201         struct comedi_subdevice *s;
2202         int ret, pages, i;
2203         unsigned short master;
2204         unsigned int irq;
2205         unsigned long iobase_a, iobase_9;
2206         struct pci_dev *pcidev;
2207         int opt_bus, opt_slot;
2208         const char *errstr;
2209         unsigned char pci_bus, pci_slot, pci_func;
2210         u16 u16w;
2211
2212         printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
2213
2214         opt_bus = it->options[0];
2215         opt_slot = it->options[1];
2216         if (it->options[3] & 1) {
2217                 master = 0;     /* user don't want use bus master */
2218         } else {
2219                 master = 1;
2220         }
2221
2222         ret = alloc_private(dev, sizeof(struct pci9118_private));
2223         if (ret < 0) {
2224                 printk(" - Allocation failed!\n");
2225                 return -ENOMEM;
2226         }
2227
2228         /* Look for matching PCI device */
2229         errstr = "not found!";
2230         pcidev = NULL;
2231         while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
2232                                                 this_board->device_id,
2233                                                 pcidev))) {
2234                 /* Found matching vendor/device. */
2235                 if (opt_bus || opt_slot) {
2236                         /* Check bus/slot. */
2237                         if (opt_bus != pcidev->bus->number
2238                             || opt_slot != PCI_SLOT(pcidev->devfn))
2239                                 continue;       /* no match */
2240                 }
2241                 /*
2242                  * Look for device that isn't in use.
2243                  * Enable PCI device and request regions.
2244                  */
2245                 if (comedi_pci_enable(pcidev, "adl_pci9118")) {
2246                         errstr =
2247                             "failed to enable PCI device and request regions!";
2248                         continue;
2249                 }
2250                 break;
2251         }
2252
2253         if (!pcidev) {
2254                 if (opt_bus || opt_slot) {
2255                         printk(KERN_ERR " - Card at b:s %d:%d %s\n",
2256                                opt_bus, opt_slot, errstr);
2257                 } else {
2258                         printk(KERN_ERR " - Card %s\n", errstr);
2259                 }
2260                 return -EIO;
2261         }
2262
2263         if (master)
2264                 pci_set_master(pcidev);
2265
2266
2267         pci_bus = pcidev->bus->number;
2268         pci_slot = PCI_SLOT(pcidev->devfn);
2269         pci_func = PCI_FUNC(pcidev->devfn);
2270         irq = pcidev->irq;
2271         iobase_a = pci_resource_start(pcidev, 0);
2272         iobase_9 = pci_resource_start(pcidev, 2);
2273
2274         printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus,
2275                                 pci_slot, pci_func, iobase_9, iobase_a);
2276
2277         dev->iobase = iobase_9;
2278         dev->board_name = this_board->name;
2279
2280         devpriv->pcidev = pcidev;
2281         devpriv->iobase_a = iobase_a;
2282
2283         pci9118_reset(dev);
2284
2285         if (it->options[3] & 2)
2286                 irq = 0;        /* user don't want use IRQ */
2287         if (irq > 0) {
2288                 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2289                                 "ADLink PCI-9118", dev)) {
2290                         printk(", unable to allocate IRQ %d, DISABLING IT",
2291                                irq);
2292                         irq = 0;        /* Can't use IRQ */
2293                 } else {
2294                         printk(", irq=%u", irq);
2295                 }
2296         } else {
2297                 printk(", IRQ disabled");
2298         }
2299
2300         dev->irq = irq;
2301
2302         if (master) {           /* alloc DMA buffers */
2303                 devpriv->dma_doublebuf = 0;
2304                 for (i = 0; i < 2; i++) {
2305                         for (pages = 4; pages >= 0; pages--) {
2306                                 devpriv->dmabuf_virt[i] =
2307                                     (short *)__get_free_pages(GFP_KERNEL,
2308                                                               pages);
2309                                 if (devpriv->dmabuf_virt[i])
2310                                         break;
2311                         }
2312                         if (devpriv->dmabuf_virt[i]) {
2313                                 devpriv->dmabuf_pages[i] = pages;
2314                                 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
2315                                 devpriv->dmabuf_samples[i] =
2316                                     devpriv->dmabuf_size[i] >> 1;
2317                                 devpriv->dmabuf_hw[i] =
2318                                     virt_to_bus((void *)
2319                                                 devpriv->dmabuf_virt[i]);
2320                         }
2321                 }
2322                 if (!devpriv->dmabuf_virt[0]) {
2323                         printk(", Can't allocate DMA buffer, DMA disabled!");
2324                         master = 0;
2325                 }
2326
2327                 if (devpriv->dmabuf_virt[1])
2328                         devpriv->dma_doublebuf = 1;
2329
2330         }
2331
2332         devpriv->master = master;
2333         if (devpriv->master)
2334                 printk(", bus master");
2335         else
2336                 printk(", no bus master");
2337
2338         devpriv->usemux = 0;
2339         if (it->options[2] > 0) {
2340                 devpriv->usemux = it->options[2];
2341                 if (devpriv->usemux > 256)
2342                         devpriv->usemux = 256;  /* max 256 channels! */
2343                 if (it->options[4] > 0)
2344                         if (devpriv->usemux > 128) {
2345                                 devpriv->usemux = 128;
2346                                         /* max 128 channels with softare S&H! */
2347                         }
2348                 printk(", ext. mux %d channels", devpriv->usemux);
2349         }
2350
2351         devpriv->softsshdelay = it->options[4];
2352         if (devpriv->softsshdelay < 0) {
2353                                         /* select sample&hold signal polarity */
2354                 devpriv->softsshdelay = -devpriv->softsshdelay;
2355                 devpriv->softsshsample = 0x80;
2356                 devpriv->softsshhold = 0x00;
2357         } else {
2358                 devpriv->softsshsample = 0x00;
2359                 devpriv->softsshhold = 0x80;
2360         }
2361
2362         printk(".\n");
2363
2364         pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
2365         pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64);
2366                                 /* Enable parity check for parity error */
2367
2368         ret = alloc_subdevices(dev, 4);
2369         if (ret < 0)
2370                 return ret;
2371
2372         s = dev->subdevices + 0;
2373         dev->read_subdev = s;
2374         s->type = COMEDI_SUBD_AI;
2375         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2376         if (devpriv->usemux)
2377                 s->n_chan = devpriv->usemux;
2378         else
2379                 s->n_chan = this_board->n_aichan;
2380
2381         s->maxdata = this_board->ai_maxdata;
2382         s->len_chanlist = this_board->n_aichanlist;
2383         s->range_table = this_board->rangelist_ai;
2384         s->cancel = pci9118_ai_cancel;
2385         s->insn_read = pci9118_insn_read_ai;
2386         if (dev->irq) {
2387                 s->subdev_flags |= SDF_CMD_READ;
2388                 s->do_cmdtest = pci9118_ai_cmdtest;
2389                 s->do_cmd = pci9118_ai_cmd;
2390                 s->munge = pci9118_ai_munge;
2391         }
2392
2393         s = dev->subdevices + 1;
2394         s->type = COMEDI_SUBD_AO;
2395         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2396         s->n_chan = this_board->n_aochan;
2397         s->maxdata = this_board->ao_maxdata;
2398         s->len_chanlist = this_board->n_aochan;
2399         s->range_table = this_board->rangelist_ao;
2400         s->insn_write = pci9118_insn_write_ao;
2401         s->insn_read = pci9118_insn_read_ao;
2402
2403         s = dev->subdevices + 2;
2404         s->type = COMEDI_SUBD_DI;
2405         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2406         s->n_chan = 4;
2407         s->maxdata = 1;
2408         s->len_chanlist = 4;
2409         s->range_table = &range_digital;
2410         s->io_bits = 0;         /* all bits input */
2411         s->insn_bits = pci9118_insn_bits_di;
2412
2413         s = dev->subdevices + 3;
2414         s->type = COMEDI_SUBD_DO;
2415         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2416         s->n_chan = 4;
2417         s->maxdata = 1;
2418         s->len_chanlist = 4;
2419         s->range_table = &range_digital;
2420         s->io_bits = 0xf;       /* all bits output */
2421         s->insn_bits = pci9118_insn_bits_do;
2422
2423         devpriv->valid = 1;
2424         devpriv->i8254_osc_base = 250;  /* 250ns=4MHz */
2425         devpriv->ai_maskharderr = 0x10a;
2426                                         /* default measure crash condition */
2427         if (it->options[5])             /* disable some requested */
2428                 devpriv->ai_maskharderr &= ~it->options[5];
2429
2430         switch (this_board->ai_maxdata) {
2431         case 0xffff:
2432                 devpriv->ai16bits = 1;
2433                 break;
2434         default:
2435                 devpriv->ai16bits = 0;
2436                 break;
2437         }
2438         return 0;
2439 }
2440
2441 /*
2442 ==============================================================================
2443 */
2444 static int pci9118_detach(struct comedi_device *dev)
2445 {
2446         if (dev->private) {
2447                 if (devpriv->valid)
2448                         pci9118_reset(dev);
2449                 if (dev->irq)
2450                         free_irq(dev->irq, dev);
2451                 if (devpriv->pcidev) {
2452                         if (dev->iobase)
2453                                 comedi_pci_disable(devpriv->pcidev);
2454
2455                         pci_dev_put(devpriv->pcidev);
2456                 }
2457                 if (devpriv->dmabuf_virt[0])
2458                         free_pages((unsigned long)devpriv->dmabuf_virt[0],
2459                                    devpriv->dmabuf_pages[0]);
2460                 if (devpriv->dmabuf_virt[1])
2461                         free_pages((unsigned long)devpriv->dmabuf_virt[1],
2462                                    devpriv->dmabuf_pages[1]);
2463         }
2464
2465         return 0;
2466 }
2467
2468 /*
2469 ==============================================================================
2470 */
2471
2472 MODULE_AUTHOR("Comedi http://www.comedi.org");
2473 MODULE_DESCRIPTION("Comedi low-level driver");
2474 MODULE_LICENSE("GPL");