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

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

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