root/drivers/staging/comedi/drivers/adl_pci9118.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pci9118_amcc_setup_dma
  2. pci9118_amcc_dma_ena
  3. pci9118_amcc_int_ena
  4. pci9118_ai_reset_fifo
  5. pci9118_ai_check_chanlist
  6. pci9118_set_chanlist
  7. pci9118_ai_mode4_switch
  8. pci9118_ai_samples_ready
  9. pci9118_ai_dma_xfer
  10. pci9118_exttrg_enable
  11. pci9118_calc_divisors
  12. pci9118_start_pacer
  13. pci9118_ai_cancel
  14. pci9118_ai_munge
  15. pci9118_ai_get_onesample
  16. pci9118_ai_get_dma
  17. pci9118_interrupt
  18. pci9118_ai_cmd_start
  19. pci9118_ai_inttrig
  20. pci9118_ai_setup_dma
  21. pci9118_ai_cmd
  22. pci9118_ai_cmdtest
  23. pci9118_ai_eoc
  24. pci9118_ai_start_conv
  25. pci9118_ai_insn_read
  26. pci9118_ao_insn_write
  27. pci9118_di_insn_bits
  28. pci9118_do_insn_bits
  29. pci9118_reset
  30. pci9118_find_pci
  31. pci9118_alloc_dma
  32. pci9118_free_dma
  33. pci9118_common_attach
  34. pci9118_attach
  35. pci9118_auto_attach
  36. pci9118_detach
  37. adl_pci9118_pci_probe

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

/* [<][>][^][v][top][bottom][index][help] */