staging: comedi: me4000: convert driver to use the comedi_8254 module
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Mon, 23 Feb 2015 21:57:50 +0000 (14:57 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 Mar 2015 02:51:51 +0000 (18:51 -0800)
Some of the hardware supported by this driver include an 8254 timer. For
aesthetics, convert it to use the comedi_8254 module to provide support for
the 8254 timer.

This also fixes the (*insn_read) and (*insn_write) to work like the comedi
API expects. Currently they only read or write a single value.

It also fixes the (*insn_config). Currently the driver is attempting to
handle the configuration instructions GPCT_RESET and GPCT_SET_OPERATION.
These are just arbitrary valuse and are not real comedi configuration_ids.
They actually coorespond to:

  GPCT_RESET -> INSN_CONFIG_DIO_OUTPUT
  GPCT_SET_OPERATION -> INSN_CONFIG_ANALOG_TRIG

The number of parameters for the instructions is validated by the comedi
core in check_insn_config_length(). GPCT_RESET happens to work (insn->n == 1)
but GPCT_SET_OPERATION would fail. The INSN_CONFIG_ANALOG_TRIG expects
insn->n == 5 but GPCT_SET_OPERATION in this driver expects insn->n == 2.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/Kconfig
drivers/staging/comedi/drivers/me4000.c

index e4ef12b21d3913e9cfe7f23df6ea4353fd58a68f..77c1c99b1116c6d13955aae1c704a8f7591d0bb6 100644 (file)
@@ -970,6 +970,7 @@ config COMEDI_CB_PCIMDDA
 
 config COMEDI_ME4000
        tristate "Meilhaus ME-4000 support"
+       select COMEDI_8254
        ---help---
          Enable support for Meilhaus PCI data acquisition cards
          ME-4650, ME-4670i, ME-4680, ME-4680i and ME-4680is
index d120aa244cf9a303f8804015d481a8eaeff97de1..2d0e60d84a3292aa0e06093b0ea13be6efb5b7d2 100644 (file)
@@ -48,7 +48,7 @@ broken.
 #include "../comedidev.h"
 
 #include "comedi_fc.h"
-#include "8253.h"
+#include "comedi_8254.h"
 #include "plx9052.h"
 
 #define ME4000_FIRMWARE                "me4000_firmware.bin"
@@ -170,7 +170,6 @@ broken.
 
 struct me4000_info {
        unsigned long plx_regbase;
-       unsigned long timer_regbase;
 };
 
 enum me4000_boardid {
@@ -1259,85 +1258,6 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
        return insn->n;
 }
 
-/*=============================================================================
-  Counter section
-  ===========================================================================*/
-
-static int me4000_cnt_insn_config(struct comedi_device *dev,
-                                 struct comedi_subdevice *s,
-                                 struct comedi_insn *insn,
-                                 unsigned int *data)
-{
-       struct me4000_info *info = dev->private;
-       unsigned int chan = CR_CHAN(insn->chanspec);
-       int err;
-
-       switch (data[0]) {
-       case GPCT_RESET:
-               if (insn->n != 1)
-                       return -EINVAL;
-
-               err = i8254_set_mode(info->timer_regbase, 0, chan,
-                                    I8254_MODE0 | I8254_BINARY);
-               if (err)
-                       return err;
-               i8254_write(info->timer_regbase, 0, chan, 0);
-               break;
-       case GPCT_SET_OPERATION:
-               if (insn->n != 2)
-                       return -EINVAL;
-
-               err = i8254_set_mode(info->timer_regbase, 0, chan,
-                               (data[1] << 1) | I8254_BINARY);
-               if (err)
-                       return err;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return insn->n;
-}
-
-static int me4000_cnt_insn_read(struct comedi_device *dev,
-                               struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
-{
-       struct me4000_info *info = dev->private;
-
-       if (insn->n == 0)
-               return 0;
-
-       if (insn->n > 1) {
-               dev_err(dev->class_dev, "Invalid instruction length %d\n",
-                       insn->n);
-               return -EINVAL;
-       }
-
-       data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec);
-
-       return 1;
-}
-
-static int me4000_cnt_insn_write(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
-{
-       struct me4000_info *info = dev->private;
-
-       if (insn->n == 0) {
-               return 0;
-       } else if (insn->n > 1) {
-               dev_err(dev->class_dev, "Invalid instruction length %d\n",
-                       insn->n);
-               return -EINVAL;
-       }
-
-       i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]);
-
-       return 1;
-}
-
 static int me4000_auto_attach(struct comedi_device *dev,
                              unsigned long context)
 {
@@ -1364,8 +1284,7 @@ static int me4000_auto_attach(struct comedi_device *dev,
 
        info->plx_regbase = pci_resource_start(pcidev, 1);
        dev->iobase = pci_resource_start(pcidev, 2);
-       info->timer_regbase = pci_resource_start(pcidev, 3);
-       if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
+       if (!info->plx_regbase || !dev->iobase)
                return -ENODEV;
 
        result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE,
@@ -1462,20 +1381,19 @@ static int me4000_auto_attach(struct comedi_device *dev,
                        dev->iobase + ME4000_DIO_DIR_REG);
        }
 
-    /*=========================================================================
-      Counter subdevice
-      ========================================================================*/
-
+       /* Counter subdevice (8254) */
        s = &dev->subdevices[3];
-
        if (thisboard->has_counter) {
-               s->type = COMEDI_SUBD_COUNTER;
-               s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-               s->n_chan = 3;
-               s->maxdata = 0xFFFF;    /*  16 bit counters */
-               s->insn_read = me4000_cnt_insn_read;
-               s->insn_write = me4000_cnt_insn_write;
-               s->insn_config = me4000_cnt_insn_config;
+               unsigned long timer_base = pci_resource_start(pcidev, 3);
+
+               if (!timer_base)
+                       return -ENODEV;
+
+               dev->pacer = comedi_8254_init(timer_base, 0, I8254_IO8, 0);
+               if (!dev->pacer)
+                       return -ENOMEM;
+
+               comedi_8254_subdevice_init(s, dev->pacer);
        } else {
                s->type = COMEDI_SUBD_UNUSED;
        }