Version:  2.0.40 2.2.26 2.4.37 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 3.18 3.19 4.0

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 can't be used if cmd->scan_begin_src=TRIG_FOLLOW
 40  *  and is used flag CMDF_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] - ignored
 53  * [4] - sample&hold signal - card can generate signal for external S&H board
 54  *       0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
 55  *       0 != use ADCHN7(pin 23) signal is generated from driver, number say how
 56  *              long delay is requested in ns and sign polarity of the hold
 57  *              (in this case external multiplexor can serve only 128 channels)
 58  * [5] - ignored
 59  */
 60 
 61 /*
 62  * FIXME
 63  *
 64  * All the supported boards have the same PCI vendor and device IDs, so
 65  * auto-attachment of PCI devices will always find the first board type.
 66  *
 67  * Perhaps the boards have different subdevice IDs that we could use to
 68  * distinguish them?
 69  *
 70  * Need some device attributes so the board type can be corrected after
 71  * attachment if necessary, and possibly to set other options supported by
 72  * manual attachment.
 73  */
 74 
 75 #include <linux/module.h>
 76 #include <linux/pci.h>
 77 #include <linux/delay.h>
 78 #include <linux/gfp.h>
 79 #include <linux/interrupt.h>
 80 #include <linux/io.h>
 81 
 82 #include "../comedidev.h"
 83 
 84 #include "amcc_s5933.h"
 85 #include "8253.h"
 86 #include "comedi_fc.h"
 87 
 88 #define IORANGE_9118    64      /* I hope */
 89 #define PCI9118_CHANLEN 255     /*
 90                                  * len of chanlist, some source say 256,
 91                                  * but reality looks like 255 :-(
 92                                  */
 93 
 94 /*
 95  * PCI BAR2 Register map (dev->iobase)
 96  */
 97 #define PCI9118_TIMER_REG(x)            (0x00 + ((x) * 4))
 98 #define PCI9118_TIMER_CTRL_REG          0x0c
 99 #define PCI9118_AI_FIFO_REG             0x10
100 #define PCI9118_AO_REG(x)               (0x10 + ((x) * 4))
101 #define PCI9118_AI_STATUS_REG           0x18
102 #define PCI9118_AI_STATUS_NFULL         (1 << 8)  /* 0=FIFO full (fatal) */
103 #define PCI9118_AI_STATUS_NHFULL        (1 << 7)  /* 0=FIFO half full */
104 #define PCI9118_AI_STATUS_NEPTY         (1 << 6)  /* 0=FIFO empty */
105 #define PCI9118_AI_STATUS_ACMP          (1 << 5)  /* 1=about trigger complete */
106 #define PCI9118_AI_STATUS_DTH           (1 << 4)  /* 1=ext. digital trigger */
107 #define PCI9118_AI_STATUS_BOVER         (1 << 3)  /* 1=burst overrun (fatal) */
108 #define PCI9118_AI_STATUS_ADOS          (1 << 2)  /* 1=A/D over speed (warn) */
109 #define PCI9118_AI_STATUS_ADOR          (1 << 1)  /* 1=A/D overrun (fatal) */
110 #define PCI9118_AI_STATUS_ADRDY         (1 << 0)  /* 1=A/D ready */
111 #define PCI9118_AI_CTRL_REG             0x18
112 #define PCI9118_AI_CTRL_UNIP            (1 << 7)  /* 1=unipolar */
113 #define PCI9118_AI_CTRL_DIFF            (1 << 6)  /* 1=differential inputs */
114 #define PCI9118_AI_CTRL_SOFTG           (1 << 5)  /* 1=8254 software gate */
115 #define PCI9118_AI_CTRL_EXTG            (1 << 4)  /* 1=8254 TGIN(pin 46) gate */
116 #define PCI9118_AI_CTRL_EXTM            (1 << 3)  /* 1=ext. trigger (pin 44) */
117 #define PCI9118_AI_CTRL_TMRTR           (1 << 2)  /* 1=8254 is trigger source */
118 #define PCI9118_AI_CTRL_INT             (1 << 1)  /* 1=enable interrupt */
119 #define PCI9118_AI_CTRL_DMA             (1 << 0)  /* 1=enable DMA */
120 #define PCI9118_DIO_REG                 0x1c
121 #define PCI9118_SOFTTRG_REG             0x20
122 #define PCI9118_AI_CHANLIST_REG         0x24
123 #define PCI9118_AI_CHANLIST_RANGE(x)    (((x) & 0x3) << 8)
124 #define PCI9118_AI_CHANLIST_CHAN(x)     ((x) << 0)
125 #define PCI9118_AI_BURST_NUM_REG        0x28
126 #define PCI9118_AI_AUTOSCAN_MODE_REG    0x2c
127 #define PCI9118_AI_CFG_REG              0x30
128 #define PCI9118_AI_CFG_PDTRG            (1 << 7)  /* 1=positive trigger */
129 #define PCI9118_AI_CFG_PETRG            (1 << 6)  /* 1=positive ext. trigger */
130 #define PCI9118_AI_CFG_BSSH             (1 << 5)  /* 1=with sample & hold */
131 #define PCI9118_AI_CFG_BM               (1 << 4)  /* 1=burst mode */
132 #define PCI9118_AI_CFG_BS               (1 << 3)  /* 1=burst mode start */
133 #define PCI9118_AI_CFG_PM               (1 << 2)  /* 1=post trigger */
134 #define PCI9118_AI_CFG_AM               (1 << 1)  /* 1=about trigger */
135 #define PCI9118_AI_CFG_START            (1 << 0)  /* 1=trigger start */
136 #define PCI9118_FIFO_RESET_REG          0x34
137 #define PCI9118_INT_CTRL_REG            0x38
138 #define PCI9118_INT_CTRL_TIMER          (1 << 3)  /* timer interrupt */
139 #define PCI9118_INT_CTRL_ABOUT          (1 << 2)  /* about trigger complete */
140 #define PCI9118_INT_CTRL_HFULL          (1 << 1)  /* A/D FIFO half full */
141 #define PCI9118_INT_CTRL_DTRG           (1 << 0)  /* ext. digital trigger */
142 
143 #define START_AI_EXT    0x01    /* start measure on external trigger */
144 #define STOP_AI_EXT     0x02    /* stop measure on external trigger */
145 #define STOP_AI_INT     0x08    /* stop measure on internal trigger */
146 
147 #define PCI9118_HALF_FIFO_SZ    (1024 / 2)
148 
149 static const struct comedi_lrange pci9118_ai_range = {
150         8, {
151                 BIP_RANGE(5),
152                 BIP_RANGE(2.5),
153                 BIP_RANGE(1.25),
154                 BIP_RANGE(0.625),
155                 UNI_RANGE(10),
156                 UNI_RANGE(5),
157                 UNI_RANGE(2.5),
158                 UNI_RANGE(1.25)
159         }
160 };
161 
162 static const struct comedi_lrange pci9118hg_ai_range = {
163         8, {
164                 BIP_RANGE(5),
165                 BIP_RANGE(0.5),
166                 BIP_RANGE(0.05),
167                 BIP_RANGE(0.005),
168                 UNI_RANGE(10),
169                 UNI_RANGE(1),
170                 UNI_RANGE(0.1),
171                 UNI_RANGE(0.01)
172         }
173 };
174 
175 #define PCI9118_BIPOLAR_RANGES  4       /*
176                                          * used for test on mixture
177                                          * of BIP/UNI ranges
178                                          */
179 
180 enum pci9118_boardid {
181         BOARD_PCI9118DG,
182         BOARD_PCI9118HG,
183         BOARD_PCI9118HR,
184 };
185 
186 struct pci9118_boardinfo {
187         const char *name;
188         unsigned int ai_is_16bit:1;
189         unsigned int is_hg:1;
190 };
191 
192 static const struct pci9118_boardinfo pci9118_boards[] = {
193         [BOARD_PCI9118DG] = {
194                 .name           = "pci9118dg",
195         },
196         [BOARD_PCI9118HG] = {
197                 .name           = "pci9118hg",
198                 .is_hg          = 1,
199         },
200         [BOARD_PCI9118HR] = {
201                 .name           = "pci9118hr",
202                 .ai_is_16bit    = 1,
203         },
204 };
205 
206 struct pci9118_dmabuf {
207         unsigned short *virt;   /* virtual address of buffer */
208         dma_addr_t hw;          /* hardware (bus) address of buffer */
209         unsigned int size;      /* size of dma buffer in bytes */
210         unsigned int use_size;  /* which size we may now use for transfer */
211 };
212 
213 struct pci9118_private {
214         unsigned long iobase_a; /* base+size for AMCC chip */
215         unsigned int master:1;
216         unsigned int dma_doublebuf:1;
217         unsigned int ai_neverending:1;
218         unsigned int usedma:1;
219         unsigned int usemux:1;
220         unsigned char ai_ctrl;
221         unsigned char int_ctrl;
222         unsigned char ai_cfg;
223         unsigned int ai_do;             /* what do AI? 0=nothing, 1 to 4 mode */
224         unsigned int ai_n_realscanlen;  /*
225                                          * what we must transfer for one
226                                          * outgoing scan include front/back adds
227                                          */
228         unsigned int ai_act_dmapos;     /* position in actual real stream */
229         unsigned int ai_add_front;      /*
230                                          * how many channels we must add
231                                          * before scan to satisfy S&H?
232                                          */
233         unsigned int ai_add_back;       /*
234                                          * how many channels we must add
235                                          * before scan to satisfy DMA?
236                                          */
237         unsigned int ai_flags;
238         char ai12_startstop;            /*
239                                          * measure can start/stop
240                                          * on external trigger
241                                          */
242         unsigned int ai_divisor1, ai_divisor2;  /*
243                                                  * divisors for start of measure
244                                                  * on external start
245                                                  */
246         unsigned int dma_actbuf;                /* which buffer is used now */
247         struct pci9118_dmabuf dmabuf[2];
248         int softsshdelay;               /*
249                                          * >0 use software S&H,
250                                          * numer is requested delay in ns
251                                          */
252         unsigned char softsshsample;    /*
253                                          * polarity of S&H signal
254                                          * in sample state
255                                          */
256         unsigned char softsshhold;      /*
257                                          * polarity of S&H signal
258                                          * in hold state
259                                          */
260         unsigned int ai_ns_min;
261 };
262 
263 static void pci9118_amcc_setup_dma(struct comedi_device *dev, unsigned int buf)
264 {
265         struct pci9118_private *devpriv = dev->private;
266         struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[buf];
267 
268         /* set the master write address and transfer count */
269         outl(dmabuf->hw, devpriv->iobase_a + AMCC_OP_REG_MWAR);
270         outl(dmabuf->use_size, devpriv->iobase_a + AMCC_OP_REG_MWTC);
271 }
272 
273 static void pci9118_amcc_dma_ena(struct comedi_device *dev, bool enable)
274 {
275         struct pci9118_private *devpriv = dev->private;
276         unsigned int mcsr;
277 
278         mcsr = inl(devpriv->iobase_a + AMCC_OP_REG_MCSR);
279         if (enable)
280                 mcsr |= RESET_A2P_FLAGS | A2P_HI_PRIORITY | EN_A2P_TRANSFERS;
281         else
282                 mcsr &= ~EN_A2P_TRANSFERS;
283         outl(mcsr, devpriv->iobase_a + AMCC_OP_REG_MCSR);
284 }
285 
286 static void pci9118_amcc_int_ena(struct comedi_device *dev, bool enable)
287 {
288         struct pci9118_private *devpriv = dev->private;
289         unsigned int intcsr;
290 
291         /* enable/disable interrupt for AMCC Incoming Mailbox 4 (32-bit) */
292         intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
293         if (enable)
294                 intcsr |= 0x1f00;
295         else
296                 intcsr &= ~0x1f00;
297         outl(intcsr, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
298 }
299 
300 static void pci9118_timer_write(struct comedi_device *dev,
301                                 unsigned int timer, unsigned int val)
302 {
303         outl(val & 0xff, dev->iobase + PCI9118_TIMER_REG(timer));
304         outl((val >> 8) & 0xff, dev->iobase + PCI9118_TIMER_REG(timer));
305 }
306 
307 static void pci9118_timer_set_mode(struct comedi_device *dev,
308                                    unsigned int timer, unsigned int mode)
309 {
310         unsigned int val;
311 
312         val = timer << 6;       /* select timer */
313         val |= 0x30;            /* load low then high byte */
314         val |= mode;            /* set timer mode and BCD|binary */
315         outl(val, dev->iobase + PCI9118_TIMER_CTRL_REG);
316 }
317 
318 static void pci9118_ai_reset_fifo(struct comedi_device *dev)
319 {
320         /* writing any value resets the A/D FIFO */
321         outl(0, dev->iobase + PCI9118_FIFO_RESET_REG);
322 }
323 
324 static int check_channel_list(struct comedi_device *dev,
325                               struct comedi_subdevice *s, int n_chan,
326                               unsigned int *chanlist, int frontadd, int backadd)
327 {
328         struct pci9118_private *devpriv = dev->private;
329         unsigned int i, differencial = 0, bipolar = 0;
330 
331         /* correct channel and range number check itself comedi/range.c */
332         if (n_chan < 1) {
333                 dev_err(dev->class_dev, "range/channel list is empty!\n");
334                 return 0;
335         }
336         if ((frontadd + n_chan + backadd) > s->len_chanlist) {
337                 dev_err(dev->class_dev,
338                         "range/channel list is too long for actual configuration!\n");
339                 return 0;
340         }
341 
342         if (CR_AREF(chanlist[0]) == AREF_DIFF)
343                 differencial = 1;       /* all input must be diff */
344         if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
345                 bipolar = 1;    /* all input must be bipolar */
346         if (n_chan > 1)
347                 for (i = 1; i < n_chan; i++) {  /* check S.E/diff */
348                         if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
349                             (differencial)) {
350                                 dev_err(dev->class_dev,
351                                         "Differential and single ended inputs can't be mixed!\n");
352                                 return 0;
353                         }
354                         if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
355                             (bipolar)) {
356                                 dev_err(dev->class_dev,
357                                         "Bipolar and unipolar ranges can't be mixed!\n");
358                                 return 0;
359                         }
360                         if (!devpriv->usemux && differencial &&
361                             (CR_CHAN(chanlist[i]) >= (s->n_chan / 2))) {
362                                 dev_err(dev->class_dev,
363                                         "AREF_DIFF is only available for the first 8 channels!\n");
364                                 return 0;
365                         }
366                 }
367 
368         return 1;
369 }
370 
371 static void pci9118_set_chanlist(struct comedi_device *dev,
372                                  struct comedi_subdevice *s,
373                                  int n_chan, unsigned int *chanlist,
374                                  int frontadd, int backadd)
375 {
376         struct pci9118_private *devpriv = dev->private;
377         unsigned int chan0 = CR_CHAN(chanlist[0]);
378         unsigned int range0 = CR_RANGE(chanlist[0]);
379         unsigned int aref0 = CR_AREF(chanlist[0]);
380         unsigned int ssh = 0x00;
381         unsigned int val;
382         int i;
383 
384         /*
385          * Configure analog input based on the first chanlist entry.
386          * All entries are either unipolar or bipolar and single-ended
387          * or differential.
388          */
389         devpriv->ai_ctrl = 0;
390         if (comedi_range_is_unipolar(s, range0))
391                 devpriv->ai_ctrl |= PCI9118_AI_CTRL_UNIP;
392         if (aref0 == AREF_DIFF)
393                 devpriv->ai_ctrl |= PCI9118_AI_CTRL_DIFF;
394         outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
395 
396         /* gods know why this sequence! */
397         outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
398         outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
399         outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
400 
401         /* insert channels for S&H */
402         if (frontadd) {
403                 val = PCI9118_AI_CHANLIST_CHAN(chan0) |
404                       PCI9118_AI_CHANLIST_RANGE(range0);
405                 ssh = devpriv->softsshsample;
406                 for (i = 0; i < frontadd; i++) {
407                         outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
408                         ssh = devpriv->softsshhold;
409                 }
410         }
411 
412         /* store chanlist */
413         for (i = 0; i < n_chan; i++) {
414                 unsigned int chan = CR_CHAN(chanlist[i]);
415                 unsigned int range = CR_RANGE(chanlist[i]);
416 
417                 val = PCI9118_AI_CHANLIST_CHAN(chan) |
418                       PCI9118_AI_CHANLIST_RANGE(range);
419                 outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
420         }
421 
422         /* insert channels to fit onto 32bit DMA */
423         if (backadd) {
424                 val = PCI9118_AI_CHANLIST_CHAN(chan0) |
425                       PCI9118_AI_CHANLIST_RANGE(range0);
426                 for (i = 0; i < backadd; i++)
427                         outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
428         }
429         /* close scan queue */
430         outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
431         /* udelay(100); important delay, or first sample will be crippled */
432 }
433 
434 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev,
435                                               unsigned int next_buf)
436 {
437         struct pci9118_private *devpriv = dev->private;
438         struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[next_buf];
439 
440         devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG |
441                           PCI9118_AI_CFG_AM;
442         outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
443         pci9118_timer_set_mode(dev, 0, I8254_MODE0);
444         pci9118_timer_write(dev, 0, dmabuf->hw >> 1);
445         devpriv->ai_cfg |= PCI9118_AI_CFG_START;
446         outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
447 }
448 
449 static unsigned int valid_samples_in_act_dma_buf(struct comedi_device *dev,
450                                                  struct comedi_subdevice *s,
451                                                  unsigned int n_raw_samples)
452 {
453         struct pci9118_private *devpriv = dev->private;
454         struct comedi_cmd *cmd = &s->async->cmd;
455         unsigned int start_pos = devpriv->ai_add_front;
456         unsigned int stop_pos = start_pos + cmd->chanlist_len;
457         unsigned int span_len = stop_pos + devpriv->ai_add_back;
458         unsigned int dma_pos = devpriv->ai_act_dmapos;
459         unsigned int whole_spans, n_samples, x;
460 
461         if (span_len == cmd->chanlist_len)
462                 return n_raw_samples;   /* use all samples */
463 
464         /*
465          * Not all samples are to be used.  Buffer contents consist of a
466          * possibly non-whole number of spans and a region of each span
467          * is to be used.
468          *
469          * Account for samples in whole number of spans.
470          */
471         whole_spans = n_raw_samples / span_len;
472         n_samples = whole_spans * cmd->chanlist_len;
473         n_raw_samples -= whole_spans * span_len;
474 
475         /*
476          * Deal with remaining samples which could overlap up to two spans.
477          */
478         while (n_raw_samples) {
479                 if (dma_pos < start_pos) {
480                         /* Skip samples before start position. */
481                         x = start_pos - dma_pos;
482                         if (x > n_raw_samples)
483                                 x = n_raw_samples;
484                         dma_pos += x;
485                         n_raw_samples -= x;
486                         if (!n_raw_samples)
487                                 break;
488                 }
489                 if (dma_pos < stop_pos) {
490                         /* Include samples before stop position. */
491                         x = stop_pos - dma_pos;
492                         if (x > n_raw_samples)
493                                 x = n_raw_samples;
494                         n_samples += x;
495                         dma_pos += x;
496                         n_raw_samples -= x;
497                 }
498                 /* Advance to next span. */
499                 start_pos += span_len;
500                 stop_pos += span_len;
501         }
502         return n_samples;
503 }
504 
505 static void move_block_from_dma(struct comedi_device *dev,
506                                 struct comedi_subdevice *s,
507                                 unsigned short *dma_buffer,
508                                 unsigned int n_raw_samples)
509 {
510         struct pci9118_private *devpriv = dev->private;
511         struct comedi_cmd *cmd = &s->async->cmd;
512         unsigned int start_pos = devpriv->ai_add_front;
513         unsigned int stop_pos = start_pos + cmd->chanlist_len;
514         unsigned int span_len = stop_pos + devpriv->ai_add_back;
515         unsigned int dma_pos = devpriv->ai_act_dmapos;
516         unsigned int x;
517 
518         if (span_len == cmd->chanlist_len) {
519                 /* All samples are to be copied. */
520                 comedi_buf_write_samples(s, dma_buffer, n_raw_samples);
521                 dma_pos += n_raw_samples;
522         } else {
523                 /*
524                  * Not all samples are to be copied.  Buffer contents consist
525                  * of a possibly non-whole number of spans and a region of
526                  * each span is to be copied.
527                  */
528                 while (n_raw_samples) {
529                         if (dma_pos < start_pos) {
530                                 /* Skip samples before start position. */
531                                 x = start_pos - dma_pos;
532                                 if (x > n_raw_samples)
533                                         x = n_raw_samples;
534                                 dma_pos += x;
535                                 n_raw_samples -= x;
536                                 if (!n_raw_samples)
537                                         break;
538                         }
539                         if (dma_pos < stop_pos) {
540                                 /* Copy samples before stop position. */
541                                 x = stop_pos - dma_pos;
542                                 if (x > n_raw_samples)
543                                         x = n_raw_samples;
544                                 comedi_buf_write_samples(s, dma_buffer, x);
545                                 dma_pos += x;
546                                 n_raw_samples -= x;
547                         }
548                         /* Advance to next span. */
549                         start_pos += span_len;
550                         stop_pos += span_len;
551                 }
552         }
553         /* Update position in span for next time. */
554         devpriv->ai_act_dmapos = dma_pos % span_len;
555 }
556 
557 static void pci9118_exttrg_enable(struct comedi_device *dev, bool enable)
558 {
559         struct pci9118_private *devpriv = dev->private;
560 
561         if (enable)
562                 devpriv->int_ctrl |= PCI9118_INT_CTRL_DTRG;
563         else
564                 devpriv->int_ctrl &= ~PCI9118_INT_CTRL_DTRG;
565         outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
566 
567         if (devpriv->int_ctrl)
568                 pci9118_amcc_int_ena(dev, true);
569         else
570                 pci9118_amcc_int_ena(dev, false);
571 }
572 
573 static void pci9118_calc_divisors(struct comedi_device *dev,
574                                   struct comedi_subdevice *s,
575                                   unsigned int *tim1, unsigned int *tim2,
576                                   unsigned int flags, int chans,
577                                   unsigned int *div1, unsigned int *div2,
578                                   unsigned int chnsshfront)
579 {
580         struct comedi_cmd *cmd = &s->async->cmd;
581 
582         *div1 = *tim2 / I8254_OSC_BASE_4MHZ;    /* convert timer (burst) */
583         *div2 = *tim1 / I8254_OSC_BASE_4MHZ;    /* scan timer */
584         *div2 = *div2 / *div1;                  /* major timer is c1*c2 */
585         if (*div2 < chans)
586                 *div2 = chans;
587 
588         *tim2 = *div1 * I8254_OSC_BASE_4MHZ;    /* real convert timer */
589 
590         if (cmd->convert_src == TRIG_NOW && !chnsshfront) {
591                 /* use BSSH signal */
592                 if (*div2 < (chans + 2))
593                         *div2 = chans + 2;
594         }
595 
596         *tim1 = *div1 * *div2 * I8254_OSC_BASE_4MHZ;
597 }
598 
599 static void pci9118_start_pacer(struct comedi_device *dev, int mode)
600 {
601         struct pci9118_private *devpriv = dev->private;
602 
603         pci9118_timer_set_mode(dev, 1, I8254_MODE2);
604         pci9118_timer_set_mode(dev, 2, I8254_MODE2);
605         udelay(1);
606 
607         if ((mode == 1) || (mode == 2) || (mode == 4)) {
608                 pci9118_timer_write(dev, 2, devpriv->ai_divisor2);
609                 pci9118_timer_write(dev, 1, devpriv->ai_divisor1);
610         }
611 }
612 
613 static int pci9118_ai_cancel(struct comedi_device *dev,
614                              struct comedi_subdevice *s)
615 {
616         struct pci9118_private *devpriv = dev->private;
617 
618         if (devpriv->usedma)
619                 pci9118_amcc_dma_ena(dev, false);
620         pci9118_exttrg_enable(dev, false);
621         pci9118_start_pacer(dev, 0);    /* stop 8254 counters */
622         /* set default config (disable burst and triggers) */
623         devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
624         outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
625         /* reset acqusition control */
626         devpriv->ai_ctrl = 0;
627         outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
628         outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
629         /* reset scan queue */
630         outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
631         outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
632         pci9118_ai_reset_fifo(dev);
633 
634         devpriv->int_ctrl = 0;
635         outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
636         pci9118_amcc_int_ena(dev, false);
637 
638         devpriv->ai_do = 0;
639         devpriv->usedma = 0;
640 
641         devpriv->ai_act_dmapos = 0;
642         s->async->inttrig = NULL;
643         devpriv->ai_neverending = 0;
644         devpriv->dma_actbuf = 0;
645 
646         return 0;
647 }
648 
649 static void pci9118_ai_munge(struct comedi_device *dev,
650                              struct comedi_subdevice *s, void *data,
651                              unsigned int num_bytes,
652                              unsigned int start_chan_index)
653 {
654         struct pci9118_private *devpriv = dev->private;
655         unsigned short *array = data;
656         unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
657         unsigned int i;
658 
659         for (i = 0; i < num_samples; i++) {
660                 if (devpriv->usedma)
661                         array[i] = be16_to_cpu(array[i]);
662                 if (s->maxdata == 0xffff)
663                         array[i] ^= 0x8000;
664                 else
665                         array[i] = (array[i] >> 4) & 0x0fff;
666 
667         }
668 }
669 
670 static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
671                                            struct comedi_subdevice *s)
672 {
673         struct pci9118_private *devpriv = dev->private;
674         struct comedi_cmd *cmd = &s->async->cmd;
675         unsigned short sampl;
676 
677         sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG);
678 
679         comedi_buf_write_samples(s, &sampl, 1);
680 
681         if (!devpriv->ai_neverending) {
682                 if (s->async->scans_done >= cmd->stop_arg)
683                         s->async->events |= COMEDI_CB_EOA;
684         }
685 }
686 
687 static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
688                                      struct comedi_subdevice *s)
689 {
690         struct pci9118_private *devpriv = dev->private;
691         struct comedi_cmd *cmd = &s->async->cmd;
692         struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[devpriv->dma_actbuf];
693         unsigned int n_all = comedi_bytes_to_samples(s, dmabuf->use_size);
694         unsigned int n_valid;
695         bool more_dma;
696 
697         /* determine whether more DMA buffers to do after this one */
698         n_valid = valid_samples_in_act_dma_buf(dev, s, n_all);
699         more_dma = n_valid < comedi_nsamples_left(s, n_valid + 1);
700 
701         /* switch DMA buffers and restart DMA if double buffering */
702         if (more_dma && devpriv->dma_doublebuf) {
703                 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
704                 pci9118_amcc_setup_dma(dev, devpriv->dma_actbuf);
705                 if (devpriv->ai_do == 4) {
706                         interrupt_pci9118_ai_mode4_switch(dev,
707                                                           devpriv->dma_actbuf);
708                 }
709         }
710 
711         if (n_all)
712                 move_block_from_dma(dev, s, dmabuf->virt, n_all);
713 
714         if (!devpriv->ai_neverending) {
715                 if (s->async->scans_done >= cmd->stop_arg)
716                         s->async->events |= COMEDI_CB_EOA;
717         }
718 
719         if (s->async->events & COMEDI_CB_CANCEL_MASK)
720                 more_dma = false;
721 
722         /* restart DMA if not double buffering */
723         if (more_dma && !devpriv->dma_doublebuf) {
724                 pci9118_amcc_setup_dma(dev, 0);
725                 if (devpriv->ai_do == 4)
726                         interrupt_pci9118_ai_mode4_switch(dev, 0);
727         }
728 }
729 
730 static irqreturn_t pci9118_interrupt(int irq, void *d)
731 {
732         struct comedi_device *dev = d;
733         struct comedi_subdevice *s = dev->read_subdev;
734         struct pci9118_private *devpriv = dev->private;
735         unsigned int intsrc;    /* IRQ reasons from card */
736         unsigned int intcsr;    /* INT register from AMCC chip */
737         unsigned int adstat;    /* STATUS register */
738 
739         if (!dev->attached)
740                 return IRQ_NONE;
741 
742         intsrc = inl(dev->iobase + PCI9118_INT_CTRL_REG) & 0xf;
743         intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
744 
745         if (!intsrc && !(intcsr & ANY_S593X_INT))
746                 return IRQ_NONE;
747 
748         outl(intcsr | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
749 
750         if (intcsr & MASTER_ABORT_INT) {
751                 dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
752                 s->async->events |= COMEDI_CB_ERROR;
753                 goto interrupt_exit;
754         }
755 
756         if (intcsr & TARGET_ABORT_INT) {
757                 dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
758                 s->async->events |= COMEDI_CB_ERROR;
759                 goto interrupt_exit;
760         }
761 
762         adstat = inl(dev->iobase + PCI9118_AI_STATUS_REG);
763         if ((adstat & PCI9118_AI_STATUS_NFULL) == 0) {
764                 dev_err(dev->class_dev,
765                         "A/D FIFO Full status (Fatal Error!)\n");
766                 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
767                 goto interrupt_exit;
768         }
769         if (adstat & PCI9118_AI_STATUS_BOVER) {
770                 dev_err(dev->class_dev,
771                         "A/D Burst Mode Overrun Status (Fatal Error!)\n");
772                 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
773                 goto interrupt_exit;
774         }
775         if (adstat & PCI9118_AI_STATUS_ADOS) {
776                 dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
777                 s->async->events |= COMEDI_CB_ERROR;
778                 goto interrupt_exit;
779         }
780         if (adstat & PCI9118_AI_STATUS_ADOR) {
781                 dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
782                 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
783                 goto interrupt_exit;
784         }
785 
786         if (!devpriv->ai_do)
787                 return IRQ_HANDLED;
788 
789         if (devpriv->ai12_startstop) {
790                 if ((adstat & PCI9118_AI_STATUS_DTH) &&
791                     (intsrc & PCI9118_INT_CTRL_DTRG)) {
792                         /* start/stop of measure */
793                         if (devpriv->ai12_startstop & START_AI_EXT) {
794                                 /* deactivate EXT trigger */
795                                 devpriv->ai12_startstop &= ~START_AI_EXT;
796                                 if (!(devpriv->ai12_startstop & STOP_AI_EXT))
797                                         pci9118_exttrg_enable(dev, false);
798 
799                                 /* start pacer */
800                                 pci9118_start_pacer(dev, devpriv->ai_do);
801                                 outl(devpriv->ai_ctrl,
802                                      dev->iobase + PCI9118_AI_CTRL_REG);
803                         } else if (devpriv->ai12_startstop & STOP_AI_EXT) {
804                                 /* deactivate EXT trigger */
805                                 devpriv->ai12_startstop &= ~STOP_AI_EXT;
806                                 pci9118_exttrg_enable(dev, false);
807 
808                                 /* on next interrupt measure will stop */
809                                 devpriv->ai_neverending = 0;
810                         }
811                 }
812         }
813 
814         if (devpriv->usedma)
815                 interrupt_pci9118_ai_dma(dev, s);
816         else
817                 interrupt_pci9118_ai_onesample(dev, s);
818 
819 interrupt_exit:
820         comedi_handle_events(dev, s);
821         return IRQ_HANDLED;
822 }
823 
824 static void pci9118_ai_cmd_start(struct comedi_device *dev)
825 {
826         struct pci9118_private *devpriv = dev->private;
827 
828         outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
829         outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
830         if (devpriv->ai_do != 3) {
831                 pci9118_start_pacer(dev, devpriv->ai_do);
832                 devpriv->ai_ctrl |= PCI9118_AI_CTRL_SOFTG;
833         }
834         outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
835 }
836 
837 static int pci9118_ai_inttrig(struct comedi_device *dev,
838                               struct comedi_subdevice *s,
839                               unsigned int trig_num)
840 {
841         struct comedi_cmd *cmd = &s->async->cmd;
842 
843         if (trig_num != cmd->start_arg)
844                 return -EINVAL;
845 
846         s->async->inttrig = NULL;
847         pci9118_ai_cmd_start(dev);
848 
849         return 1;
850 }
851 
852 static int Compute_and_setup_dma(struct comedi_device *dev,
853                                  struct comedi_subdevice *s)
854 {
855         struct pci9118_private *devpriv = dev->private;
856         struct comedi_cmd *cmd = &s->async->cmd;
857         struct pci9118_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
858         struct pci9118_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
859         unsigned int dmalen0, dmalen1, i;
860 
861         dmalen0 = dmabuf0->size;
862         dmalen1 = dmabuf1->size;
863         /* isn't output buff smaller that our DMA buff? */
864         if (dmalen0 > s->async->prealloc_bufsz) {
865                 /* align to 32bit down */
866                 dmalen0 = s->async->prealloc_bufsz & ~3L;
867         }
868         if (dmalen1 > s->async->prealloc_bufsz) {
869                 /* align to 32bit down */
870                 dmalen1 = s->async->prealloc_bufsz & ~3L;
871         }
872 
873         /* we want wake up every scan? */
874         if (devpriv->ai_flags & CMDF_WAKE_EOS) {
875                 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
876                         /* uff, too short DMA buffer, disable EOS support! */
877                         devpriv->ai_flags &= (~CMDF_WAKE_EOS);
878                         dev_info(dev->class_dev,
879                                  "WAR: DMA0 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
880                                   dmalen0, devpriv->ai_n_realscanlen << 1);
881                 } else {
882                         /* short first DMA buffer to one scan */
883                         dmalen0 = devpriv->ai_n_realscanlen << 1;
884                         if (dmalen0 < 4) {
885                                 dev_info(dev->class_dev,
886                                          "ERR: DMA0 buf len bug? (%d<4)\n",
887                                          dmalen0);
888                                 dmalen0 = 4;
889                         }
890                 }
891         }
892         if (devpriv->ai_flags & CMDF_WAKE_EOS) {
893                 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
894                         /* uff, too short DMA buffer, disable EOS support! */
895                         devpriv->ai_flags &= (~CMDF_WAKE_EOS);
896                         dev_info(dev->class_dev,
897                                  "WAR: DMA1 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
898                                  dmalen1, devpriv->ai_n_realscanlen << 1);
899                 } else {
900                         /* short second DMA buffer to one scan */
901                         dmalen1 = devpriv->ai_n_realscanlen << 1;
902                         if (dmalen1 < 4) {
903                                 dev_info(dev->class_dev,
904                                          "ERR: DMA1 buf len bug? (%d<4)\n",
905                                          dmalen1);
906                                 dmalen1 = 4;
907                         }
908                 }
909         }
910 
911         /* transfer without CMDF_WAKE_EOS */
912         if (!(devpriv->ai_flags & CMDF_WAKE_EOS)) {
913                 /* if it's possible then align DMA buffers to length of scan */
914                 i = dmalen0;
915                 dmalen0 =
916                     (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
917                     (devpriv->ai_n_realscanlen << 1);
918                 dmalen0 &= ~3L;
919                 if (!dmalen0)
920                         dmalen0 = i;    /* uff. very long scan? */
921                 i = dmalen1;
922                 dmalen1 =
923                     (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
924                     (devpriv->ai_n_realscanlen << 1);
925                 dmalen1 &= ~3L;
926                 if (!dmalen1)
927                         dmalen1 = i;    /* uff. very long scan? */
928                 /*
929                  * if measure isn't neverending then test, if it fits whole
930                  * into one or two DMA buffers
931                  */
932                 if (!devpriv->ai_neverending) {
933                         /* fits whole measure into one DMA buffer? */
934                         if (dmalen0 >
935                             ((devpriv->ai_n_realscanlen << 1) *
936                              cmd->stop_arg)) {
937                                 dmalen0 =
938                                     (devpriv->ai_n_realscanlen << 1) *
939                                     cmd->stop_arg;
940                                 dmalen0 &= ~3L;
941                         } else {        /*
942                                          * fits whole measure into
943                                          * two DMA buffer?
944                                          */
945                                 if (dmalen1 >
946                                     ((devpriv->ai_n_realscanlen << 1) *
947                                      cmd->stop_arg - dmalen0))
948                                         dmalen1 =
949                                             (devpriv->ai_n_realscanlen << 1) *
950                                             cmd->stop_arg - dmalen0;
951                                 dmalen1 &= ~3L;
952                         }
953                 }
954         }
955 
956         /* these DMA buffer size will be used */
957         devpriv->dma_actbuf = 0;
958         dmabuf0->use_size = dmalen0;
959         dmabuf1->use_size = dmalen1;
960 
961         pci9118_amcc_dma_ena(dev, false);
962         pci9118_amcc_setup_dma(dev, 0);
963         /* init DMA transfer */
964         outl(0x00000000 | AINT_WRITE_COMPL,
965              devpriv->iobase_a + AMCC_OP_REG_INTCSR);
966 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
967         pci9118_amcc_dma_ena(dev, true);
968         outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
969                         devpriv->iobase_a + AMCC_OP_REG_INTCSR);
970                                                 /* allow bus mastering */
971 
972         return 0;
973 }
974 
975 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
976 {
977         struct pci9118_private *devpriv = dev->private;
978         struct comedi_cmd *cmd = &s->async->cmd;
979         unsigned int addchans = 0;
980 
981         devpriv->ai12_startstop = 0;
982         devpriv->ai_flags = cmd->flags;
983         devpriv->ai_add_front = 0;
984         devpriv->ai_add_back = 0;
985 
986         /* prepare for start/stop conditions */
987         if (cmd->start_src == TRIG_EXT)
988                 devpriv->ai12_startstop |= START_AI_EXT;
989         if (cmd->stop_src == TRIG_EXT) {
990                 devpriv->ai_neverending = 1;
991                 devpriv->ai12_startstop |= STOP_AI_EXT;
992         }
993         if (cmd->stop_src == TRIG_NONE)
994                 devpriv->ai_neverending = 1;
995         if (cmd->stop_src == TRIG_COUNT)
996                 devpriv->ai_neverending = 0;
997 
998         /*
999          * use additional sample at end of every scan
1000          * to satisty DMA 32 bit transfer?
1001          */
1002         devpriv->ai_add_front = 0;
1003         devpriv->ai_add_back = 0;
1004         if (devpriv->master) {
1005                 devpriv->usedma = 1;
1006                 if ((cmd->flags & CMDF_WAKE_EOS) &&
1007                     (cmd->scan_end_arg == 1)) {
1008                         if (cmd->convert_src == TRIG_NOW)
1009                                 devpriv->ai_add_back = 1;
1010                         if (cmd->convert_src == TRIG_TIMER) {
1011                                 devpriv->usedma = 0;
1012                                         /*
1013                                          * use INT transfer if scanlist
1014                                          * have only one channel
1015                                          */
1016                         }
1017                 }
1018                 if ((cmd->flags & CMDF_WAKE_EOS) &&
1019                     (cmd->scan_end_arg & 1) &&
1020                     (cmd->scan_end_arg > 1)) {
1021                         if (cmd->scan_begin_src == TRIG_FOLLOW) {
1022                                 devpriv->usedma = 0;
1023                                 /*
1024                                  * XXX maybe can be corrected to use 16 bit DMA
1025                                  */
1026                         } else {        /*
1027                                          * well, we must insert one sample
1028                                          * to end of EOS to meet 32 bit transfer
1029                                          */
1030                                 devpriv->ai_add_back = 1;
1031                         }
1032                 }
1033         } else {        /* interrupt transfer don't need any correction */
1034                 devpriv->usedma = 0;
1035         }
1036 
1037         /*
1038          * we need software S&H signal?
1039          * It adds two samples before every scan as minimum
1040          */
1041         if (cmd->convert_src == TRIG_NOW && devpriv->softsshdelay) {
1042                 devpriv->ai_add_front = 2;
1043                 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1044                                                         /* move it to front */
1045                         devpriv->ai_add_front++;
1046                         devpriv->ai_add_back = 0;
1047                 }
1048                 if (cmd->convert_arg < devpriv->ai_ns_min)
1049                         cmd->convert_arg = devpriv->ai_ns_min;
1050                 addchans = devpriv->softsshdelay / cmd->convert_arg;
1051                 if (devpriv->softsshdelay % cmd->convert_arg)
1052                         addchans++;
1053                 if (addchans > (devpriv->ai_add_front - 1)) {
1054                                                         /* uff, still short */
1055                         devpriv->ai_add_front = addchans + 1;
1056                         if (devpriv->usedma == 1)
1057                                 if ((devpriv->ai_add_front +
1058                                      cmd->chanlist_len +
1059                                      devpriv->ai_add_back) & 1)
1060                                         devpriv->ai_add_front++;
1061                                                         /* round up to 32 bit */
1062                 }
1063         }
1064         /* well, we now know what must be all added */
1065         devpriv->ai_n_realscanlen =     /*
1066                                          * what we must take from card in real
1067                                          * to have cmd->scan_end_arg on output?
1068                                          */
1069             (devpriv->ai_add_front + cmd->chanlist_len +
1070              devpriv->ai_add_back) * (cmd->scan_end_arg /
1071                                       cmd->chanlist_len);
1072 
1073         /* check and setup channel list */
1074         if (!check_channel_list(dev, s, cmd->chanlist_len,
1075                                 cmd->chanlist, devpriv->ai_add_front,
1076                                 devpriv->ai_add_back))
1077                 return -EINVAL;
1078 
1079         /*
1080          * Configure analog input and load the chanlist.
1081          * The acqusition control bits are enabled later.
1082          */
1083         pci9118_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist,
1084                              devpriv->ai_add_front, devpriv->ai_add_back);
1085 
1086         /* Determine acqusition mode and calculate timing */
1087         devpriv->ai_do = 0;
1088         if (cmd->scan_begin_src != TRIG_TIMER &&
1089             cmd->convert_src == TRIG_TIMER) {
1090                 /* cascaded timers 1 and 2 are used for convert timing */
1091                 if (cmd->scan_begin_src == TRIG_EXT)
1092                         devpriv->ai_do = 4;
1093                 else
1094                         devpriv->ai_do = 1;
1095 
1096                 i8253_cascade_ns_to_timer(I8254_OSC_BASE_4MHZ,
1097                                           &devpriv->ai_divisor1,
1098                                           &devpriv->ai_divisor2,
1099                                           &cmd->convert_arg,
1100                                           devpriv->ai_flags &
1101                                           CMDF_ROUND_NEAREST);
1102 
1103                 devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
1104 
1105                 if (!devpriv->usedma) {
1106                         devpriv->ai_ctrl |= PCI9118_AI_CTRL_INT;
1107                         devpriv->int_ctrl |= PCI9118_INT_CTRL_TIMER;
1108                 }
1109 
1110                 if (cmd->scan_begin_src == TRIG_EXT) {
1111                         struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[0];
1112 
1113                         devpriv->ai_cfg |= PCI9118_AI_CFG_AM;
1114                         outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1115                         pci9118_timer_set_mode(dev, 0, I8254_MODE0);
1116                         pci9118_timer_write(dev, 0, dmabuf->hw >> 1);
1117                         devpriv->ai_cfg |= PCI9118_AI_CFG_START;
1118                 }
1119         }
1120 
1121         if (cmd->scan_begin_src == TRIG_TIMER &&
1122             cmd->convert_src != TRIG_EXT) {
1123                 if (!devpriv->usedma) {
1124                         dev_err(dev->class_dev,
1125                                 "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!\n");
1126                         return -EIO;
1127                 }
1128 
1129                 /* double timed action */
1130                 devpriv->ai_do = 2;
1131 
1132                 pci9118_calc_divisors(dev, s,
1133                                       &cmd->scan_begin_arg, &cmd->convert_arg,
1134                                       devpriv->ai_flags,
1135                                       devpriv->ai_n_realscanlen,
1136                                       &devpriv->ai_divisor1,
1137                                       &devpriv->ai_divisor2,
1138                                       devpriv->ai_add_front);
1139 
1140                 devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
1141                 devpriv->ai_cfg |= PCI9118_AI_CFG_BM | PCI9118_AI_CFG_BS;
1142                 if (cmd->convert_src == TRIG_NOW && !devpriv->softsshdelay)
1143                         devpriv->ai_cfg |= PCI9118_AI_CFG_BSSH;
1144                 outl(devpriv->ai_n_realscanlen,
1145                      dev->iobase + PCI9118_AI_BURST_NUM_REG);
1146         }
1147 
1148         if (cmd->scan_begin_src == TRIG_FOLLOW &&
1149             cmd->convert_src == TRIG_EXT) {
1150                 /* external trigger conversion */
1151                 devpriv->ai_do = 3;
1152 
1153                 devpriv->ai_ctrl |= PCI9118_AI_CTRL_EXTM;
1154         }
1155 
1156         if (devpriv->ai_do == 0) {
1157                 dev_err(dev->class_dev,
1158                         "Unable to determine acqusition mode! BUG in (*do_cmdtest)?\n");
1159                 return -EINVAL;
1160         }
1161 
1162         if (devpriv->usedma)
1163                 devpriv->ai_ctrl |= PCI9118_AI_CTRL_DMA;
1164 
1165         pci9118_start_pacer(dev, -1);   /* stop pacer */
1166 
1167         /* set default config (disable burst and triggers) */
1168         devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
1169         outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1170         udelay(1);
1171         pci9118_ai_reset_fifo(dev);
1172 
1173         /* clear A/D and INT status registers */
1174         inl(dev->iobase + PCI9118_AI_STATUS_REG);
1175         inl(dev->iobase + PCI9118_INT_CTRL_REG);
1176 
1177         devpriv->ai_act_dmapos = 0;
1178 
1179         if (devpriv->usedma) {
1180                 Compute_and_setup_dma(dev, s);
1181 
1182                 outl(0x02000000 | AINT_WRITE_COMPL,
1183                      devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1184         } else {
1185                 pci9118_amcc_int_ena(dev, true);
1186         }
1187 
1188         /* start async command now or wait for internal trigger */
1189         if (cmd->start_src == TRIG_NOW)
1190                 pci9118_ai_cmd_start(dev);
1191         else if (cmd->start_src == TRIG_INT)
1192                 s->async->inttrig = pci9118_ai_inttrig;
1193 
1194         /* enable external trigger for command start/stop */
1195         if (cmd->start_src == TRIG_EXT || cmd->stop_src == TRIG_EXT)
1196                 pci9118_exttrg_enable(dev, true);
1197 
1198         return 0;
1199 }
1200 
1201 static int pci9118_ai_cmdtest(struct comedi_device *dev,
1202                               struct comedi_subdevice *s,
1203                               struct comedi_cmd *cmd)
1204 {
1205         struct pci9118_private *devpriv = dev->private;
1206         int err = 0;
1207         unsigned int flags;
1208         unsigned int arg;
1209         unsigned int divisor1 = 0, divisor2 = 0;
1210 
1211         /* Step 1 : check if triggers are trivially valid */
1212 
1213         err |= cfc_check_trigger_src(&cmd->start_src,
1214                                         TRIG_NOW | TRIG_EXT | TRIG_INT);
1215 
1216         flags = TRIG_FOLLOW;
1217         if (devpriv->master)
1218                 flags |= TRIG_TIMER | TRIG_EXT;
1219         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1220 
1221         flags = TRIG_TIMER | TRIG_EXT;
1222         if (devpriv->master)
1223                 flags |= TRIG_NOW;
1224         err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1225 
1226         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1227         err |= cfc_check_trigger_src(&cmd->stop_src,
1228                                         TRIG_COUNT | TRIG_NONE | TRIG_EXT);
1229 
1230         if (err)
1231                 return 1;
1232 
1233         /* Step 2a : make sure trigger sources are unique */
1234 
1235         err |= cfc_check_trigger_is_unique(cmd->start_src);
1236         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1237         err |= cfc_check_trigger_is_unique(cmd->convert_src);
1238         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1239 
1240         /* Step 2b : and mutually compatible */
1241 
1242         if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1243                 err |= -EINVAL;
1244 
1245         if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT)
1246                 err |= -EINVAL;
1247 
1248         if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1249             (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW))))
1250                 err |= -EINVAL;
1251 
1252         if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1253             (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT))))
1254                 err |= -EINVAL;
1255 
1256         if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1257                 err |= -EINVAL;
1258 
1259         if (err)
1260                 return 2;
1261 
1262         /* Step 3: check if arguments are trivially valid */
1263 
1264         switch (cmd->start_src) {
1265         case TRIG_NOW:
1266         case TRIG_EXT:
1267                 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1268                 break;
1269         case TRIG_INT:
1270                 /* start_arg is the internal trigger (any value) */
1271                 break;
1272         }
1273 
1274         if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1275                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1276 
1277         if ((cmd->scan_begin_src == TRIG_TIMER) &&
1278             (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1279                 cmd->scan_begin_src = TRIG_FOLLOW;
1280                 cmd->convert_arg = cmd->scan_begin_arg;
1281                 cmd->scan_begin_arg = 0;
1282         }
1283 
1284         if (cmd->scan_begin_src == TRIG_TIMER)
1285                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1286                                                  devpriv->ai_ns_min);
1287 
1288         if (cmd->scan_begin_src == TRIG_EXT)
1289                 if (cmd->scan_begin_arg) {
1290                         cmd->scan_begin_arg = 0;
1291                         err |= -EINVAL;
1292                         err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg,
1293                                                          65535);
1294                 }
1295 
1296         if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
1297                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
1298                                                  devpriv->ai_ns_min);
1299 
1300         if (cmd->convert_src == TRIG_EXT)
1301                 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
1302 
1303         if (cmd->stop_src == TRIG_COUNT)
1304                 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
1305         else    /* TRIG_NONE */
1306                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1307 
1308         err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
1309 
1310         err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg,
1311                                          cmd->chanlist_len);
1312 
1313         if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1314                 cmd->scan_end_arg =
1315                     cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1316                 err |= -EINVAL;
1317         }
1318 
1319         if (err)
1320                 return 3;
1321 
1322         /* step 4: fix up any arguments */
1323 
1324         if (cmd->scan_begin_src == TRIG_TIMER) {
1325                 arg = cmd->scan_begin_arg;
1326                 i8253_cascade_ns_to_timer(I8254_OSC_BASE_4MHZ,
1327                                           &divisor1, &divisor2,
1328                                           &arg, cmd->flags);
1329                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1330         }
1331 
1332         if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1333                 arg = cmd->convert_arg;
1334                 i8253_cascade_ns_to_timer(I8254_OSC_BASE_4MHZ,
1335                                           &divisor1, &divisor2,
1336                                           &arg, cmd->flags);
1337                 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
1338 
1339                 if (cmd->scan_begin_src == TRIG_TIMER &&
1340                     cmd->convert_src == TRIG_NOW) {
1341                         if (cmd->convert_arg == 0) {
1342                                 arg = devpriv->ai_ns_min *
1343                                       (cmd->scan_end_arg + 2);
1344                         } else {
1345                                 arg = cmd->convert_arg * cmd->chanlist_len;
1346                         }
1347                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1348                                                          arg);
1349                 }
1350         }
1351 
1352         if (err)
1353                 return 4;
1354 
1355         if (cmd->chanlist)
1356                 if (!check_channel_list(dev, s, cmd->chanlist_len,
1357                                         cmd->chanlist, 0, 0))
1358                         return 5;       /* incorrect channels list */
1359 
1360         return 0;
1361 }
1362 
1363 static int pci9118_ai_eoc(struct comedi_device *dev,
1364                           struct comedi_subdevice *s,
1365                           struct comedi_insn *insn,
1366                           unsigned long context)
1367 {
1368         unsigned int status;
1369 
1370         status = inl(dev->iobase + PCI9118_AI_STATUS_REG);
1371         if (status & PCI9118_AI_STATUS_ADRDY)
1372                 return 0;
1373         return -EBUSY;
1374 }
1375 
1376 static void pci9118_ai_start_conv(struct comedi_device *dev)
1377 {
1378         /* writing any value triggers an A/D conversion */
1379         outl(0, dev->iobase + PCI9118_SOFTTRG_REG);
1380 }
1381 
1382 static int pci9118_ai_insn_read(struct comedi_device *dev,
1383                                 struct comedi_subdevice *s,
1384                                 struct comedi_insn *insn,
1385                                 unsigned int *data)
1386 {
1387         struct pci9118_private *devpriv = dev->private;
1388         unsigned int val;
1389         int ret;
1390         int i;
1391 
1392        /*
1393         * Configure analog input based on the chanspec.
1394         * Acqusition is software controlled without interrupts.
1395         */
1396         pci9118_set_chanlist(dev, s, 1, &insn->chanspec, 0, 0);
1397 
1398         /* set default config (disable burst and triggers) */
1399         devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
1400         outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1401 
1402         pci9118_ai_reset_fifo(dev);
1403 
1404         for (i = 0; i < insn->n; i++) {
1405                 pci9118_ai_start_conv(dev);
1406 
1407                 ret = comedi_timeout(dev, s, insn, pci9118_ai_eoc, 0);
1408                 if (ret)
1409                         return ret;
1410 
1411                 val = inl(dev->iobase + PCI9118_AI_FIFO_REG);
1412                 if (s->maxdata == 0xffff)
1413                         data[i] = (val & 0xffff) ^ 0x8000;
1414                 else
1415                         data[i] = (val >> 4) & 0xfff;
1416         }
1417 
1418         return insn->n;
1419 }
1420 
1421 static int pci9118_ao_insn_write(struct comedi_device *dev,
1422                                  struct comedi_subdevice *s,
1423                                  struct comedi_insn *insn,
1424                                  unsigned int *data)
1425 {
1426         unsigned int chan = CR_CHAN(insn->chanspec);
1427         unsigned int val = s->readback[chan];
1428         int i;
1429 
1430         for (i = 0; i < insn->n; i++) {
1431                 val = data[i];
1432                 outl(val, dev->iobase + PCI9118_AO_REG(chan));
1433         }
1434         s->readback[chan] = val;
1435 
1436         return insn->n;
1437 }
1438 
1439 static int pci9118_di_insn_bits(struct comedi_device *dev,
1440                                 struct comedi_subdevice *s,
1441                                 struct comedi_insn *insn,
1442                                 unsigned int *data)
1443 {
1444         /*
1445          * The digital inputs and outputs share the read register.
1446          * bits [7:4] are the digital outputs
1447          * bits [3:0] are the digital inputs
1448          */
1449         data[1] = inl(dev->iobase + PCI9118_DIO_REG) & 0xf;
1450 
1451         return insn->n;
1452 }
1453 
1454 static int pci9118_do_insn_bits(struct comedi_device *dev,
1455                                 struct comedi_subdevice *s,
1456                                 struct comedi_insn *insn,
1457                                 unsigned int *data)
1458 {
1459         /*
1460          * The digital outputs are set with the same register that
1461          * the digital inputs and outputs are read from. But the
1462          * outputs are set with bits [3:0] so we can simply write
1463          * the s->state to set them.
1464          */
1465         if (comedi_dio_update_state(s, data))
1466                 outl(s->state, dev->iobase + PCI9118_DIO_REG);
1467 
1468         data[1] = s->state;
1469 
1470         return insn->n;
1471 }
1472 
1473 static void pci9118_reset(struct comedi_device *dev)
1474 {
1475         /* reset analog input subsystem */
1476         outl(0, dev->iobase + PCI9118_INT_CTRL_REG);
1477         outl(0, dev->iobase + PCI9118_AI_CTRL_REG);
1478         outl(0, dev->iobase + PCI9118_AI_CFG_REG);
1479         pci9118_ai_reset_fifo(dev);
1480 
1481         /* clear any pending interrupts and status */
1482         inl(dev->iobase + PCI9118_INT_CTRL_REG);
1483         inl(dev->iobase + PCI9118_AI_STATUS_REG);
1484 
1485         /* reset and stop counters */
1486         pci9118_timer_set_mode(dev, 0, I8254_MODE0);
1487         pci9118_start_pacer(dev, 0);
1488 
1489         /* reset DMA and scan queue */
1490         outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
1491         outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
1492         outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
1493 
1494         /* reset analog outputs to 0V */
1495         outl(2047, dev->iobase + PCI9118_AO_REG(0));
1496         outl(2047, dev->iobase + PCI9118_AO_REG(1));
1497 }
1498 
1499 static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
1500                                         struct comedi_devconfig *it)
1501 {
1502         struct pci_dev *pcidev = NULL;
1503         int bus = it->options[0];
1504         int slot = it->options[1];
1505 
1506         for_each_pci_dev(pcidev) {
1507                 if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
1508                         continue;
1509                 if (pcidev->device != 0x80d9)
1510                         continue;
1511                 if (bus || slot) {
1512                         /* requested particular bus/slot */
1513                         if (pcidev->bus->number != bus ||
1514                             PCI_SLOT(pcidev->devfn) != slot)
1515                                 continue;
1516                 }
1517                 return pcidev;
1518         }
1519         dev_err(dev->class_dev,
1520                 "no supported board found! (req. bus/slot : %d/%d)\n",
1521                 bus, slot);
1522         return NULL;
1523 }
1524 
1525 static void pci9118_alloc_dma(struct comedi_device *dev)
1526 {
1527         struct pci9118_private *devpriv = dev->private;
1528         struct pci9118_dmabuf *dmabuf;
1529         int order;
1530         int i;
1531 
1532         for (i = 0; i < 2; i++) {
1533                 dmabuf = &devpriv->dmabuf[i];
1534                 for (order = 2; order >= 0; order--) {
1535                         dmabuf->virt =
1536                             dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order,
1537                                                &dmabuf->hw, GFP_KERNEL);
1538                         if (dmabuf->virt)
1539                                 break;
1540                 }
1541                 if (!dmabuf->virt)
1542                         break;
1543                 dmabuf->size = PAGE_SIZE << order;
1544 
1545                 if (i == 0)
1546                         devpriv->master = 1;
1547                 if (i == 1)
1548                         devpriv->dma_doublebuf = 1;
1549         }
1550 }
1551 
1552 static void pci9118_free_dma(struct comedi_device *dev)
1553 {
1554         struct pci9118_private *devpriv = dev->private;
1555         struct pci9118_dmabuf *dmabuf;
1556         int i;
1557 
1558         if (!devpriv)
1559                 return;
1560 
1561         for (i = 0; i < 2; i++) {
1562                 dmabuf = &devpriv->dmabuf[i];
1563                 if (dmabuf->virt) {
1564                         dma_free_coherent(dev->hw_dev, dmabuf->size,
1565                                           dmabuf->virt, dmabuf->hw);
1566                 }
1567         }
1568 }
1569 
1570 static int pci9118_common_attach(struct comedi_device *dev,
1571                                  int ext_mux, int softsshdelay)
1572 {
1573         const struct pci9118_boardinfo *board = dev->board_ptr;
1574         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1575         struct pci9118_private *devpriv;
1576         struct comedi_subdevice *s;
1577         int ret;
1578         int i;
1579         u16 u16w;
1580 
1581         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1582         if (!devpriv)
1583                 return -ENOMEM;
1584 
1585         ret = comedi_pci_enable(dev);
1586         if (ret)
1587                 return ret;
1588         pci_set_master(pcidev);
1589 
1590         devpriv->iobase_a = pci_resource_start(pcidev, 0);
1591         dev->iobase = pci_resource_start(pcidev, 2);
1592 
1593         pci9118_reset(dev);
1594 
1595         if (pcidev->irq) {
1596                 ret = request_irq(pcidev->irq, pci9118_interrupt, IRQF_SHARED,
1597                                   dev->board_name, dev);
1598                 if (ret == 0) {
1599                         dev->irq = pcidev->irq;
1600 
1601                         pci9118_alloc_dma(dev);
1602                 }
1603         }
1604 
1605         if (ext_mux > 0) {
1606                 if (ext_mux > 256)
1607                         ext_mux = 256;  /* max 256 channels! */
1608                 if (softsshdelay > 0)
1609                         if (ext_mux > 128)
1610                                 ext_mux = 128;
1611                 devpriv->usemux = 1;
1612         } else {
1613                 devpriv->usemux = 0;
1614         }
1615 
1616         if (softsshdelay < 0) {
1617                 /* select sample&hold signal polarity */
1618                 devpriv->softsshdelay = -softsshdelay;
1619                 devpriv->softsshsample = 0x80;
1620                 devpriv->softsshhold = 0x00;
1621         } else {
1622                 devpriv->softsshdelay = softsshdelay;
1623                 devpriv->softsshsample = 0x00;
1624                 devpriv->softsshhold = 0x80;
1625         }
1626 
1627         pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
1628         pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
1629                                 /* Enable parity check for parity error */
1630 
1631         ret = comedi_alloc_subdevices(dev, 4);
1632         if (ret)
1633                 return ret;
1634 
1635         /* Analog Input subdevice */
1636         s = &dev->subdevices[0];
1637         s->type         = COMEDI_SUBD_AI;
1638         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1639         s->n_chan       = (devpriv->usemux) ? ext_mux : 16;
1640         s->maxdata      = board->ai_is_16bit ? 0xffff : 0x0fff;
1641         s->range_table  = board->is_hg ? &pci9118hg_ai_range
1642                                        : &pci9118_ai_range;
1643         s->insn_read    = pci9118_ai_insn_read;
1644         if (dev->irq) {
1645                 dev->read_subdev = s;
1646                 s->subdev_flags |= SDF_CMD_READ;
1647                 s->len_chanlist = PCI9118_CHANLEN;
1648                 s->do_cmdtest   = pci9118_ai_cmdtest;
1649                 s->do_cmd       = pci9118_ai_cmd;
1650                 s->cancel       = pci9118_ai_cancel;
1651                 s->munge        = pci9118_ai_munge;
1652         }
1653 
1654         if (s->maxdata == 0xffff) {
1655                 /*
1656                  * 16-bit samples are from an ADS7805 A/D converter.
1657                  * Minimum sampling rate is 10us.
1658                  */
1659                 devpriv->ai_ns_min = 10000;
1660         } else {
1661                 /*
1662                  * 12-bit samples are from an ADS7800 A/D converter.
1663                  * Minimum sampling rate is 3us.
1664                  */
1665                 devpriv->ai_ns_min = 3000;
1666         }
1667 
1668         /* Analog Output subdevice */
1669         s = &dev->subdevices[1];
1670         s->type         = COMEDI_SUBD_AO;
1671         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1672         s->n_chan       = 2;
1673         s->maxdata      = 0x0fff;
1674         s->range_table  = &range_bipolar10;
1675         s->insn_write   = pci9118_ao_insn_write;
1676 
1677         ret = comedi_alloc_subdev_readback(s);
1678         if (ret)
1679                 return ret;
1680 
1681         /* the analog outputs were reset to 0V, make the readback match */
1682         for (i = 0; i < s->n_chan; i++)
1683                 s->readback[i] = 2047;
1684 
1685         /* Digital Input subdevice */
1686         s = &dev->subdevices[2];
1687         s->type         = COMEDI_SUBD_DI;
1688         s->subdev_flags = SDF_READABLE;
1689         s->n_chan       = 4;
1690         s->maxdata      = 1;
1691         s->range_table  = &range_digital;
1692         s->insn_bits    = pci9118_di_insn_bits;
1693 
1694         /* Digital Output subdevice */
1695         s = &dev->subdevices[3];
1696         s->type         = COMEDI_SUBD_DO;
1697         s->subdev_flags = SDF_WRITABLE;
1698         s->n_chan       = 4;
1699         s->maxdata      = 1;
1700         s->range_table  = &range_digital;
1701         s->insn_bits    = pci9118_do_insn_bits;
1702 
1703         /* get the current state of the digital outputs */
1704         s->state = inl(dev->iobase + PCI9118_DIO_REG) >> 4;
1705 
1706         return 0;
1707 }
1708 
1709 static int pci9118_attach(struct comedi_device *dev,
1710                           struct comedi_devconfig *it)
1711 {
1712         struct pci_dev *pcidev;
1713         int ext_mux, softsshdelay;
1714 
1715         ext_mux = it->options[2];
1716         softsshdelay = it->options[4];
1717 
1718         pcidev = pci9118_find_pci(dev, it);
1719         if (!pcidev)
1720                 return -EIO;
1721         comedi_set_hw_dev(dev, &pcidev->dev);
1722 
1723         return pci9118_common_attach(dev, ext_mux, softsshdelay);
1724 }
1725 
1726 static int pci9118_auto_attach(struct comedi_device *dev,
1727                                unsigned long context)
1728 {
1729         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1730         const struct pci9118_boardinfo *board = NULL;
1731 
1732         if (context < ARRAY_SIZE(pci9118_boards))
1733                 board = &pci9118_boards[context];
1734         if (!board)
1735                 return -ENODEV;
1736         dev->board_ptr = board;
1737         dev->board_name = board->name;
1738 
1739         /*
1740          * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
1741          * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
1742          */
1743         pci_dev_get(pcidev);
1744         /* no external mux, no sample-hold delay */
1745         return pci9118_common_attach(dev, 0, 0);
1746 }
1747 
1748 static void pci9118_detach(struct comedi_device *dev)
1749 {
1750         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1751 
1752         if (dev->iobase)
1753                 pci9118_reset(dev);
1754         comedi_pci_detach(dev);
1755         pci9118_free_dma(dev);
1756         if (pcidev)
1757                 pci_dev_put(pcidev);
1758 }
1759 
1760 static struct comedi_driver adl_pci9118_driver = {
1761         .driver_name    = "adl_pci9118",
1762         .module         = THIS_MODULE,
1763         .attach         = pci9118_attach,
1764         .auto_attach    = pci9118_auto_attach,
1765         .detach         = pci9118_detach,
1766         .num_names      = ARRAY_SIZE(pci9118_boards),
1767         .board_name     = &pci9118_boards[0].name,
1768         .offset         = sizeof(struct pci9118_boardinfo),
1769 };
1770 
1771 static int adl_pci9118_pci_probe(struct pci_dev *dev,
1772                                  const struct pci_device_id *id)
1773 {
1774         return comedi_pci_auto_config(dev, &adl_pci9118_driver,
1775                                       id->driver_data);
1776 }
1777 
1778 /* FIXME: All the supported board types have the same device ID! */
1779 static const struct pci_device_id adl_pci9118_pci_table[] = {
1780         { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118DG },
1781 /*      { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HG }, */
1782 /*      { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HR }, */
1783         { 0 }
1784 };
1785 MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
1786 
1787 static struct pci_driver adl_pci9118_pci_driver = {
1788         .name           = "adl_pci9118",
1789         .id_table       = adl_pci9118_pci_table,
1790         .probe          = adl_pci9118_pci_probe,
1791         .remove         = comedi_pci_auto_unconfig,
1792 };
1793 module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
1794 
1795 MODULE_AUTHOR("Comedi http://www.comedi.org");
1796 MODULE_DESCRIPTION("Comedi low-level driver");
1797 MODULE_LICENSE("GPL");
1798 

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