Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/staging/comedi/drivers/adl_pci9118.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us