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

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

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