staging: comedi: aio_aio12_8: hookup 8254 counter/timer
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Mon, 12 Oct 2015 19:16:32 +0000 (12:16 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Oct 2015 17:26:06 +0000 (10:26 -0700)
This board has an industry-standard 8254 chip with the gate, clock,
and output pins for each counter available on the connector.

Hookup the 8254 counter as a comedi subdevice.

Provice an (*insn_config) for the user to query the clock source
for each channel.

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/aio_aio12_8.c

index a5f2a3e..ac0f010 100644 (file)
@@ -410,6 +410,7 @@ config COMEDI_FL512
 
 config COMEDI_AIO_AIO12_8
        tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support"
+       select COMEDI_8254
        select COMEDI_8255
        ---help---
          Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board
index 63fb9fd..0ba557e 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <linux/module.h>
 #include "../comedidev.h"
+
+#include "comedi_8254.h"
 #include "8255.h"
 
 /*
@@ -163,6 +165,29 @@ static int aio_aio12_8_ao_insn_write(struct comedi_device *dev,
        return insn->n;
 }
 
+static int aio_aio12_8_counter_insn_config(struct comedi_device *dev,
+                                          struct comedi_subdevice *s,
+                                          struct comedi_insn *insn,
+                                          unsigned int *data)
+{
+       unsigned int chan = CR_CHAN(insn->chanspec);
+
+       switch (data[0]) {
+       case INSN_CONFIG_GET_CLOCK_SRC:
+               /*
+                * Channels 0 and 2 have external clock sources.
+                * Channel 1 has a fixed 1 MHz clock source.
+                */
+               data[0] = 0;
+               data[1] = (chan == 1) ? I8254_OSC_BASE_1MHZ : 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return insn->n;
+}
+
 static const struct comedi_lrange range_aio_aio12_8 = {
        4, {
                UNI_RANGE(5),
@@ -183,6 +208,11 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
        if (ret)
                return ret;
 
+       dev->pacer = comedi_8254_init(dev->iobase + AIO12_8_8254_BASE_REG,
+                                     0, I8254_IO8, 0);
+       if (!dev->pacer)
+               return -ENOMEM;
+
        ret = comedi_alloc_subdevices(dev, 4);
        if (ret)
                return ret;
@@ -223,9 +253,11 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
        if (ret)
                return ret;
 
+       /* Counter subdevice (8254) */
        s = &dev->subdevices[3];
-       /* 8254 counter/timer subdevice */
-       s->type         = COMEDI_SUBD_UNUSED;
+       comedi_8254_subdevice_init(s, dev->pacer);
+
+       dev->pacer->insn_config = aio_aio12_8_counter_insn_config;
 
        return 0;
 }