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