Version:  2.0.40 2.2.26 2.4.37 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 3.16

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

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