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