staging: comedi: adv_pci1710: tidy up analog output subdev_flags
[deliverable/linux.git] / drivers / staging / comedi / drivers / adv_pci1710.c
index 399c511cfe0aba3b1e2714610512af05a6e049a8..91ab68b92086cea3a6a7ceaf6277100e2464d6c2 100644 (file)
@@ -11,8 +11,9 @@
  * Driver: adv_pci1710
  * Description: Comedi driver for Advantech PCI-1710 series boards
  * Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG, PCI-1711,
- *   PCI-1713, PCI-1720, PCI-1731
+ *   PCI-1713, PCI-1731
  * Author: Michal Dobes <dobes@tesnet.cz>
+ * Updated: Fri, 29 Oct 2015 17:19:35 -0700
  * Status: works
  *
  * Configuration options: not applicable, uses PCI auto config
 #define PCI171X_AD_DATA_REG    0x00    /* R:   A/D data */
 #define PCI171X_SOFTTRG_REG    0x00    /* W:   soft trigger for A/D */
 #define PCI171X_RANGE_REG      0x02    /* W:   A/D gain/range register */
+#define PCI171X_RANGE_DIFF     BIT(5)
+#define PCI171X_RANGE_UNI      BIT(4)
+#define PCI171X_RANGE_GAIN(x)  (((x) & 0x7) << 0)
 #define PCI171X_MUX_REG                0x04    /* W:   A/D multiplexor control */
+#define PCI171X_MUX_CHANH(x)   (((x) & 0xf) << 8)
+#define PCI171X_MUX_CHANL(x)   (((x) & 0xf) << 0)
+#define PCI171X_MUX_CHAN(x)    (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x))
 #define PCI171X_STATUS_REG     0x06    /* R:   status register */
 #define PCI171X_STATUS_IRQ     BIT(11) /* 1=IRQ occurred */
 #define PCI171X_STATUS_FF      BIT(10) /* 1=FIFO is full, fatal error */
 #define PCI171X_CLRFIFO_REG    0x09    /* W:   clear FIFO */
 #define PCI171X_DA_REG(x)      (0x0a + ((x) * 2)) /* W:   D/A register */
 #define PCI171X_DAREF_REG      0x0e    /* W:   D/A reference control */
+#define PCI171X_DAREF(c, r)    (((r) & 0x3) << ((c) * 2))
+#define PCI171X_DAREF_MASK(c)  PCI171X_DAREF((c), 0x3)
 #define PCI171X_DI_REG         0x10    /* R:   digital inputs */
 #define PCI171X_DO_REG         0x10    /* W:   digital outputs */
 #define PCI171X_TIMER_BASE     0x18    /* R/W: 8254 timer */
 
-/*
- * PCI-1720 only has analog outputs and has a different
- * register map (dev->iobase)
- */
-#define PCI1720_DA_REG(x)      (0x00 + ((x) * 2)) /* W:   D/A registers */
-#define PCI1720_RANGE_REG      0x08    /* R/W: D/A range register */
-#define PCI1720_SYNC_REG       0x09    /* W:   D/A synchronized output */
-#define PCI1720_SYNC_CTRL_REG  0x0f    /* R/W: D/A synchronized control */
-#define PCI1720_SYNC_CTRL_SC0  BIT(0)  /* set synchronous output mode */
-
-static const struct comedi_lrange range_pci1710_3 = {
+static const struct comedi_lrange pci1710_ai_range = {
        9, {
-               BIP_RANGE(5),
-               BIP_RANGE(2.5),
-               BIP_RANGE(1.25),
-               BIP_RANGE(0.625),
-               BIP_RANGE(10),
-               UNI_RANGE(10),
-               UNI_RANGE(5),
-               UNI_RANGE(2.5),
-               UNI_RANGE(1.25)
+               BIP_RANGE(5),           /* gain 1   (0x00) */
+               BIP_RANGE(2.5),         /* gain 2   (0x01) */
+               BIP_RANGE(1.25),        /* gain 4   (0x02) */
+               BIP_RANGE(0.625),       /* gain 8   (0x03) */
+               BIP_RANGE(10),          /* gain 0.5 (0x04) */
+               UNI_RANGE(10),          /* gain 1   (0x00 | UNI) */
+               UNI_RANGE(5),           /* gain 2   (0x01 | UNI) */
+               UNI_RANGE(2.5),         /* gain 4   (0x02 | UNI) */
+               UNI_RANGE(1.25)         /* gain 8   (0x03 | UNI) */
        }
 };
 
-static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
-                                             0x10, 0x11, 0x12, 0x13 };
-
-static const struct comedi_lrange range_pci1710hg = {
+static const struct comedi_lrange pci1710hg_ai_range = {
        12, {
-               BIP_RANGE(5),
-               BIP_RANGE(0.5),
-               BIP_RANGE(0.05),
-               BIP_RANGE(0.005),
-               BIP_RANGE(10),
-               BIP_RANGE(1),
-               BIP_RANGE(0.1),
-               BIP_RANGE(0.01),
-               UNI_RANGE(10),
-               UNI_RANGE(1),
-               UNI_RANGE(0.1),
-               UNI_RANGE(0.01)
+               BIP_RANGE(5),           /* gain 1    (0x00) */
+               BIP_RANGE(0.5),         /* gain 10   (0x01) */
+               BIP_RANGE(0.05),        /* gain 100  (0x02) */
+               BIP_RANGE(0.005),       /* gain 1000 (0x03) */
+               BIP_RANGE(10),          /* gain 0.5  (0x04) */
+               BIP_RANGE(1),           /* gain 5    (0x05) */
+               BIP_RANGE(0.1),         /* gain 50   (0x06) */
+               BIP_RANGE(0.01),        /* gain 500  (0x07) */
+               UNI_RANGE(10),          /* gain 1    (0x00 | UNI) */
+               UNI_RANGE(1),           /* gain 10   (0x01 | UNI) */
+               UNI_RANGE(0.1),         /* gain 100  (0x02 | UNI) */
+               UNI_RANGE(0.01)         /* gain 1000 (0x03 | UNI) */
        }
 };
 
-static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
-                                             0x05, 0x06, 0x07, 0x10, 0x11,
-                                             0x12, 0x13 };
-
-static const struct comedi_lrange range_pci17x1 = {
+static const struct comedi_lrange pci1711_ai_range = {
        5, {
-               BIP_RANGE(10),
-               BIP_RANGE(5),
-               BIP_RANGE(2.5),
-               BIP_RANGE(1.25),
-               BIP_RANGE(0.625)
-       }
-};
-
-static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
-
-static const struct comedi_lrange pci1720_ao_range = {
-       4, {
-               UNI_RANGE(5),
-               UNI_RANGE(10),
-               BIP_RANGE(5),
-               BIP_RANGE(10)
+               BIP_RANGE(10),          /* gain 1  (0x00) */
+               BIP_RANGE(5),           /* gain 2  (0x01) */
+               BIP_RANGE(2.5),         /* gain 4  (0x02) */
+               BIP_RANGE(1.25),        /* gain 8  (0x03) */
+               BIP_RANGE(0.625)        /* gain 16 (0x04) */
        }
 };
 
 static const struct comedi_lrange pci171x_ao_range = {
-       2, {
-               UNI_RANGE(5),
-               UNI_RANGE(10)
+       3, {
+               UNI_RANGE(5),           /* internal -5V ref */
+               UNI_RANGE(10),          /* internal -10V ref */
+               RANGE_ext(0, 1)         /* external -Vref (+/-10V max) */
        }
 };
 
@@ -143,82 +125,43 @@ enum pci1710_boardid {
        BOARD_PCI1710HG,
        BOARD_PCI1711,
        BOARD_PCI1713,
-       BOARD_PCI1720,
        BOARD_PCI1731,
 };
 
 struct boardtype {
-       const char *name;       /*  board name */
-       int n_aichan;           /*  num of A/D chans */
-       const struct comedi_lrange *rangelist_ai;       /*  rangelist for A/D */
-       const char *rangecode_ai;       /*  range codes for programming */
+       const char *name;
+       const struct comedi_lrange *ai_range;
+       unsigned int is_pci1711:1;
        unsigned int is_pci1713:1;
-       unsigned int is_pci1720:1;
-       unsigned int has_irq:1;
-       unsigned int has_large_fifo:1;  /* 4K or 1K FIFO */
-       unsigned int has_diff_ai:1;
        unsigned int has_ao:1;
-       unsigned int has_di_do:1;
-       unsigned int has_counter:1;
 };
 
 static const struct boardtype boardtypes[] = {
        [BOARD_PCI1710] = {
                .name           = "pci1710",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci1710_3,
-               .rangecode_ai   = range_codes_pci1710_3,
-               .has_irq        = 1,
-               .has_large_fifo = 1,
-               .has_diff_ai    = 1,
+               .ai_range       = &pci1710_ai_range,
                .has_ao         = 1,
-               .has_di_do      = 1,
-               .has_counter    = 1,
        },
        [BOARD_PCI1710HG] = {
                .name           = "pci1710hg",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci1710hg,
-               .rangecode_ai   = range_codes_pci1710hg,
-               .has_irq        = 1,
-               .has_large_fifo = 1,
-               .has_diff_ai    = 1,
+               .ai_range       = &pci1710hg_ai_range,
                .has_ao         = 1,
-               .has_di_do      = 1,
-               .has_counter    = 1,
        },
        [BOARD_PCI1711] = {
                .name           = "pci1711",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci17x1,
-               .rangecode_ai   = range_codes_pci17x1,
-               .has_irq        = 1,
+               .ai_range       = &pci1711_ai_range,
+               .is_pci1711     = 1,
                .has_ao         = 1,
-               .has_di_do      = 1,
-               .has_counter    = 1,
        },
        [BOARD_PCI1713] = {
                .name           = "pci1713",
-               .n_aichan       = 32,
-               .rangelist_ai   = &range_pci1710_3,
-               .rangecode_ai   = range_codes_pci1710_3,
+               .ai_range       = &pci1710_ai_range,
                .is_pci1713     = 1,
-               .has_irq        = 1,
-               .has_large_fifo = 1,
-               .has_diff_ai    = 1,
-       },
-       [BOARD_PCI1720] = {
-               .name           = "pci1720",
-               .is_pci1720     = 1,
-               .has_ao         = 1,
        },
        [BOARD_PCI1731] = {
                .name           = "pci1731",
-               .n_aichan       = 16,
-               .rangelist_ai   = &range_pci17x1,
-               .rangecode_ai   = range_codes_pci17x1,
-               .has_irq        = 1,
-               .has_di_do      = 1,
+               .ai_range       = &pci1711_ai_range,
+               .is_pci1711     = 1,
        },
 };
 
@@ -226,11 +169,12 @@ struct pci1710_private {
        unsigned int max_samples;
        unsigned int ctrl;      /* control register value */
        unsigned int ctrl_ext;  /* used to switch from TRIG_EXT to TRIG_xxx */
-       unsigned int mux_ext;   /* used to set the channel interval to scan */
+       unsigned int mux_scan;  /* used to set the channel interval to scan */
        unsigned char ai_et;
        unsigned int act_chanlist[32];  /*  list of scanned channel */
        unsigned char saved_seglen;     /* len of the non-repeating chanlist */
        unsigned char da_ranges;        /*  copy of D/A outpit range register */
+       unsigned char unipolar_gain;    /* adjust for unipolar gain codes */
 };
 
 static int pci171x_ai_check_chanlist(struct comedi_device *dev,
@@ -305,7 +249,6 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
                                      unsigned int n_chan,
                                      unsigned int seglen)
 {
-       const struct boardtype *board = dev->board_ptr;
        struct pci1710_private *devpriv = dev->private;
        unsigned int first_chan = CR_CHAN(chanlist[0]);
        unsigned int last_chan = CR_CHAN(chanlist[seglen - 1]);
@@ -315,14 +258,18 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
                unsigned int chan = CR_CHAN(chanlist[i]);
                unsigned int range = CR_RANGE(chanlist[i]);
                unsigned int aref = CR_AREF(chanlist[i]);
-               unsigned int rangeval;
+               unsigned int rangeval = 0;
 
-               rangeval = board->rangecode_ai[range];
                if (aref == AREF_DIFF)
-                       rangeval |= 0x0020;
+                       rangeval |= PCI171X_RANGE_DIFF;
+               if (comedi_range_is_unipolar(s, range)) {
+                       rangeval |= PCI171X_RANGE_UNI;
+                       range -= devpriv->unipolar_gain;
+               }
+               rangeval |= PCI171X_RANGE_GAIN(range);
 
                /* select channel and set range */
-               outw(chan | (chan << 8), dev->iobase + PCI171X_MUX_REG);
+               outw(PCI171X_MUX_CHAN(chan), dev->iobase + PCI171X_MUX_REG);
                outw(rangeval, dev->iobase + PCI171X_RANGE_REG);
 
                devpriv->act_chanlist[i] = chan;
@@ -331,8 +278,9 @@ static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
                devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
 
        /* select channel interval to scan */
-       devpriv->mux_ext = first_chan | (last_chan << 8);
-       outw(devpriv->mux_ext, dev->iobase + PCI171X_MUX_REG);
+       devpriv->mux_scan = PCI171X_MUX_CHANL(first_chan) |
+                           PCI171X_MUX_CHANH(last_chan);
+       outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG);
 }
 
 static int pci171x_ai_eoc(struct comedi_device *dev,
@@ -417,84 +365,6 @@ static int pci171x_ai_insn_read(struct comedi_device *dev,
        return ret ? ret : insn->n;
 }
 
-static int pci171x_ao_insn_write(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn,
-                                unsigned int *data)
-{
-       struct pci1710_private *devpriv = dev->private;
-       unsigned int chan = CR_CHAN(insn->chanspec);
-       unsigned int range = CR_RANGE(insn->chanspec);
-       unsigned int val = s->readback[chan];
-       int i;
-
-       devpriv->da_ranges &= ~(1 << (chan << 1));
-       devpriv->da_ranges |= (range << (chan << 1));
-       outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG);
-
-       for (i = 0; i < insn->n; i++) {
-               val = data[i];
-               outw(val, dev->iobase + PCI171X_DA_REG(chan));
-       }
-
-       s->readback[chan] = val;
-
-       return insn->n;
-}
-
-static int pci171x_di_insn_bits(struct comedi_device *dev,
-                               struct comedi_subdevice *s,
-                               struct comedi_insn *insn,
-                               unsigned int *data)
-{
-       data[1] = inw(dev->iobase + PCI171X_DI_REG);
-
-       return insn->n;
-}
-
-static int pci171x_do_insn_bits(struct comedi_device *dev,
-                               struct comedi_subdevice *s,
-                               struct comedi_insn *insn,
-                               unsigned int *data)
-{
-       if (comedi_dio_update_state(s, data))
-               outw(s->state, dev->iobase + PCI171X_DO_REG);
-
-       data[1] = s->state;
-
-       return insn->n;
-}
-
-static int pci1720_ao_insn_write(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn,
-                                unsigned int *data)
-{
-       struct pci1710_private *devpriv = dev->private;
-       unsigned int chan = CR_CHAN(insn->chanspec);
-       unsigned int range = CR_RANGE(insn->chanspec);
-       unsigned int val;
-       int i;
-
-       val = devpriv->da_ranges & (~(0x03 << (chan << 1)));
-       val |= (range << (chan << 1));
-       if (val != devpriv->da_ranges) {
-               outb(val, dev->iobase + PCI1720_RANGE_REG);
-               devpriv->da_ranges = val;
-       }
-
-       val = s->readback[chan];
-       for (i = 0; i < insn->n; i++) {
-               val = data[i];
-               outw(val, dev->iobase + PCI1720_DA_REG(chan));
-               outb(0, dev->iobase + PCI1720_SYNC_REG); /* update outputs */
-       }
-
-       s->readback[chan] = val;
-
-       return insn->n;
-}
-
 static int pci171x_ai_cancel(struct comedi_device *dev,
                             struct comedi_subdevice *s)
 {
@@ -598,7 +468,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev,
        outb(0, dev->iobase + PCI171X_CLRINT_REG);
 }
 
-static irqreturn_t interrupt_service_pci1710(int irq, void *d)
+static irqreturn_t pci1710_irq_handler(int irq, void *d)
 {
        struct comedi_device *dev = d;
        struct pci1710_private *devpriv = dev->private;
@@ -624,7 +494,7 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
                outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
                outb(0, dev->iobase + PCI171X_CLRINT_REG);
                /* no sample on this interrupt; reset the channel interval */
-               outw(devpriv->mux_ext, dev->iobase + PCI171X_MUX_REG);
+               outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG);
                outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
                comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
                return IRQ_HANDLED;
@@ -753,7 +623,55 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
        return 0;
 }
 
-static int pci171x_insn_counter_config(struct comedi_device *dev,
+static int pci1710_ao_insn_write(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       struct pci1710_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int range = CR_RANGE(insn->chanspec);
+       unsigned int val = s->readback[chan];
+       int i;
+
+       devpriv->da_ranges &= ~PCI171X_DAREF_MASK(chan);
+       devpriv->da_ranges |= PCI171X_DAREF(chan, range);
+       outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG);
+
+       for (i = 0; i < insn->n; i++) {
+               val = data[i];
+               outw(val, dev->iobase + PCI171X_DA_REG(chan));
+       }
+
+       s->readback[chan] = val;
+
+       return insn->n;
+}
+
+static int pci1710_di_insn_bits(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       data[1] = inw(dev->iobase + PCI171X_DI_REG);
+
+       return insn->n;
+}
+
+static int pci1710_do_insn_bits(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       if (comedi_dio_update_state(s, data))
+               outw(s->state, dev->iobase + PCI171X_DO_REG);
+
+       data[1] = s->state;
+
+       return insn->n;
+}
+
+static int pci1710_counter_insn_config(struct comedi_device *dev,
                                       struct comedi_subdevice *s,
                                       struct comedi_insn *insn,
                                       unsigned int *data)
@@ -790,7 +708,7 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
        return insn->n;
 }
 
-static int pci171x_reset(struct comedi_device *dev)
+static int pci1710_reset(struct comedi_device *dev)
 {
        const struct boardtype *board = dev->board_ptr;
        struct pci1710_private *devpriv = dev->private;
@@ -815,33 +733,6 @@ static int pci171x_reset(struct comedi_device *dev)
        return 0;
 }
 
-static int pci1720_reset(struct comedi_device *dev)
-{
-       struct pci1710_private *devpriv = dev->private;
-       /* set synchronous output mode */
-       outb(PCI1720_SYNC_CTRL_SC0, dev->iobase + PCI1720_SYNC_CTRL_REG);
-       devpriv->da_ranges = 0xAA;
-       /* set all ranges to +/-5V and outputs to 0V */
-       outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE_REG);
-       outw(0x0800, dev->iobase + PCI1720_DA_REG(0));
-       outw(0x0800, dev->iobase + PCI1720_DA_REG(1));
-       outw(0x0800, dev->iobase + PCI1720_DA_REG(2));
-       outw(0x0800, dev->iobase + PCI1720_DA_REG(3));
-       outb(0, dev->iobase + PCI1720_SYNC_REG);        /* update outputs */
-
-       return 0;
-}
-
-static int pci1710_reset(struct comedi_device *dev)
-{
-       const struct boardtype *board = dev->board_ptr;
-
-       if (board->is_pci1720)
-               return pci1720_reset(dev);
-
-       return pci171x_reset(dev);
-}
-
 static int pci1710_auto_attach(struct comedi_device *dev,
                               unsigned long context)
 {
@@ -850,6 +741,7 @@ static int pci1710_auto_attach(struct comedi_device *dev,
        struct pci1710_private *devpriv;
        struct comedi_subdevice *s;
        int ret, subdev, n_subdevices;
+       int i;
 
        if (context < ARRAY_SIZE(boardtypes))
                board = &boardtypes[context];
@@ -872,15 +764,16 @@ static int pci1710_auto_attach(struct comedi_device *dev,
        if (!dev->pacer)
                return -ENOMEM;
 
-       n_subdevices = 0;
-       if (board->n_aichan)
-               n_subdevices++;
+       n_subdevices = 1;       /* all boards have analog inputs */
        if (board->has_ao)
                n_subdevices++;
-       if (board->has_di_do)
-               n_subdevices += 2;
-       if (board->has_counter)
-               n_subdevices++;
+       if (!board->is_pci1713) {
+               /*
+                * All other boards have digital inputs and outputs as
+                * well as a user counter.
+                */
+               n_subdevices += 3;
+       }
 
        ret = comedi_alloc_subdevices(dev, n_subdevices);
        if (ret)
@@ -888,8 +781,8 @@ static int pci1710_auto_attach(struct comedi_device *dev,
 
        pci1710_reset(dev);
 
-       if (board->has_irq && pcidev->irq) {
-               ret = request_irq(pcidev->irq, interrupt_service_pci1710,
+       if (pcidev->irq) {
+               ret = request_irq(pcidev->irq, pci1710_irq_handler,
                                  IRQF_SHARED, dev->board_name, dev);
                if (ret == 0)
                        dev->irq = pcidev->irq;
@@ -897,83 +790,78 @@ static int pci1710_auto_attach(struct comedi_device *dev,
 
        subdev = 0;
 
-       if (board->n_aichan) {
-               s = &dev->subdevices[subdev];
-               s->type         = COMEDI_SUBD_AI;
-               s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
-               if (board->has_diff_ai)
-                       s->subdev_flags |= SDF_DIFF;
-               s->n_chan       = board->n_aichan;
-               s->maxdata      = 0x0fff;
-               s->range_table  = board->rangelist_ai;
-               s->insn_read    = pci171x_ai_insn_read;
-               if (dev->irq) {
-                       dev->read_subdev = s;
-                       s->subdev_flags |= SDF_CMD_READ;
-                       s->len_chanlist = s->n_chan;
-                       s->do_cmdtest   = pci171x_ai_cmdtest;
-                       s->do_cmd       = pci171x_ai_cmd;
-                       s->cancel       = pci171x_ai_cancel;
+       /* Analog Input subdevice */
+       s = &dev->subdevices[subdev];
+       s->type         = COMEDI_SUBD_AI;
+       s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
+       if (!board->is_pci1711)
+               s->subdev_flags |= SDF_DIFF;
+       s->n_chan       = board->is_pci1713 ? 32 : 16;
+       s->maxdata      = 0x0fff;
+       s->range_table  = board->ai_range;
+       s->insn_read    = pci171x_ai_insn_read;
+       if (dev->irq) {
+               dev->read_subdev = s;
+               s->subdev_flags |= SDF_CMD_READ;
+               s->len_chanlist = s->n_chan;
+               s->do_cmdtest   = pci171x_ai_cmdtest;
+               s->do_cmd       = pci171x_ai_cmd;
+               s->cancel       = pci171x_ai_cancel;
+       }
+
+       /* find the value needed to adjust for unipolar gain codes */
+       for (i = 0; i < s->range_table->length; i++) {
+               if (comedi_range_is_unipolar(s, i)) {
+                       devpriv->unipolar_gain = i;
+                       break;
                }
-               subdev++;
        }
 
+       subdev++;
+
        if (board->has_ao) {
+               /* Analog Output subdevice */
                s = &dev->subdevices[subdev];
                s->type         = COMEDI_SUBD_AO;
-               s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+               s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+               s->n_chan       = 2;
                s->maxdata      = 0x0fff;
-               if (board->is_pci1720) {
-                       s->n_chan       = 4;
-                       s->range_table  = &pci1720_ao_range;
-                       s->insn_write   = pci1720_ao_insn_write;
-               } else {
-                       s->n_chan       = 2;
-                       s->range_table  = &pci171x_ao_range;
-                       s->insn_write   = pci171x_ao_insn_write;
-               }
+               s->range_table  = &pci171x_ao_range;
+               s->insn_write   = pci1710_ao_insn_write;
 
                ret = comedi_alloc_subdev_readback(s);
                if (ret)
                        return ret;
 
-               /* initialize the readback values to match the board reset */
-               if (board->is_pci1720) {
-                       int i;
-
-                       for (i = 0; i < s->n_chan; i++)
-                               s->readback[i] = 0x0800;
-               }
-
                subdev++;
        }
 
-       if (board->has_di_do) {
+       if (!board->is_pci1713) {
+               /* Digital Input subdevice */
                s = &dev->subdevices[subdev];
                s->type         = COMEDI_SUBD_DI;
                s->subdev_flags = SDF_READABLE;
                s->n_chan       = 16;
                s->maxdata      = 1;
                s->range_table  = &range_digital;
-               s->insn_bits    = pci171x_di_insn_bits;
+               s->insn_bits    = pci1710_di_insn_bits;
                subdev++;
 
+               /* Digital Output subdevice */
                s = &dev->subdevices[subdev];
                s->type         = COMEDI_SUBD_DO;
                s->subdev_flags = SDF_WRITABLE;
                s->n_chan       = 16;
                s->maxdata      = 1;
                s->range_table  = &range_digital;
-               s->insn_bits    = pci171x_do_insn_bits;
+               s->insn_bits    = pci1710_do_insn_bits;
                subdev++;
-       }
 
-       /* Counter subdevice (8254) */
-       if (board->has_counter) {
+               /* Counter subdevice (8254) */
                s = &dev->subdevices[subdev];
                comedi_8254_subdevice_init(s, dev->pacer);
 
-               dev->pacer->insn_config = pci171x_insn_counter_config;
+               dev->pacer->insn_config = pci1710_counter_insn_config;
 
                /* counters 1 and 2 are used internally for the pacer */
                comedi_8254_set_busy(dev->pacer, 1, true);
@@ -983,23 +871,16 @@ static int pci1710_auto_attach(struct comedi_device *dev,
        }
 
        /* max_samples is half the FIFO size (2 bytes/sample) */
-       devpriv->max_samples = (board->has_large_fifo) ? 2048 : 512;
+       devpriv->max_samples = (board->is_pci1711) ? 512 : 2048;
 
        return 0;
 }
 
-static void pci1710_detach(struct comedi_device *dev)
-{
-       if (dev->iobase)
-               pci1710_reset(dev);
-       comedi_pci_detach(dev);
-}
-
 static struct comedi_driver adv_pci1710_driver = {
        .driver_name    = "adv_pci1710",
        .module         = THIS_MODULE,
        .auto_attach    = pci1710_auto_attach,
-       .detach         = pci1710_detach,
+       .detach         = comedi_pci_detach,
 };
 
 static int adv_pci1710_pci_probe(struct pci_dev *dev,
@@ -1063,7 +944,6 @@ static const struct pci_device_id adv_pci1710_pci_table[] = {
        },
        { PCI_VDEVICE(ADVANTECH, 0x1711), BOARD_PCI1711 },
        { PCI_VDEVICE(ADVANTECH, 0x1713), BOARD_PCI1713 },
-       { PCI_VDEVICE(ADVANTECH, 0x1720), BOARD_PCI1720 },
        { PCI_VDEVICE(ADVANTECH, 0x1731), BOARD_PCI1731 },
        { 0 }
 };
This page took 0.033997 seconds and 5 git commands to generate.