aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/das16m1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/das16m1.c')
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c114
1 files changed, 57 insertions, 57 deletions
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index 3666a68979fb..1adf6a71a9f3 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -53,12 +53,12 @@ irq can be omitted, although the cmd interface will not work without it.
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "8255.h"
-#include "8253.h"
-#include "comedi_fc.h"
+#include "comedi_8254.h"
#define DAS16M1_SIZE2 8
@@ -103,8 +103,6 @@ irq can be omitted, although the cmd interface will not work without it.
#define Q_RANGE(x) (((x) & 0xf) << 4)
#define UNIPOLAR 0x40
#define DAS16M1_8254_FIRST 0x8
-#define DAS16M1_8254_FIRST_CNTRL 0xb
-#define TOTAL_CLEAR 0x30
#define DAS16M1_8254_SECOND 0xc
#define DAS16M1_82C55 0x400
#define DAS16M1_8254_THIRD 0x404
@@ -124,6 +122,7 @@ static const struct comedi_lrange range_das16m1 = {
};
struct das16m1_private_struct {
+ struct comedi_8254 *counter;
unsigned int control_state;
unsigned int adc_count; /* number of samples completed */
/* initial value in lower half of hardware conversion counter,
@@ -131,8 +130,6 @@ struct das16m1_private_struct {
* counter yet (loaded by first sample conversion) */
u16 initial_hw_count;
unsigned short ai_buffer[FIFO_SIZE];
- unsigned int divisor1; /* divides master clock to obtain conversion speed */
- unsigned int divisor2; /* divides master clock to obtain conversion speed */
unsigned long extra_iobase;
};
@@ -169,7 +166,7 @@ static int das16m1_ai_check_chanlist(struct comedi_device *dev,
if ((i % 2) != (chan % 2)) {
dev_dbg(dev->class_dev,
- "even/odd channels must go have even/odd chanlist indices\n");
+ "even/odd channels must go have even/odd chanlist indices\n");
return -EINVAL;
}
}
@@ -180,26 +177,25 @@ static int das16m1_ai_check_chanlist(struct comedi_device *dev,
static int das16m1_cmd_test(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
- struct das16m1_private_struct *devpriv = dev->private;
int err = 0;
- unsigned int arg;
/* Step 1 : check if triggers are trivially valid */
- err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
- err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
+ err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
+ err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
+ err |= comedi_check_trigger_src(&cmd->convert_src,
+ TRIG_TIMER | TRIG_EXT);
+ err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
if (err)
return 1;
/* Step 2a : make sure trigger sources are unique */
- err |= cfc_check_trigger_is_unique(cmd->start_src);
- err |= cfc_check_trigger_is_unique(cmd->convert_src);
- err |= cfc_check_trigger_is_unique(cmd->stop_src);
+ err |= comedi_check_trigger_is_unique(cmd->start_src);
+ err |= comedi_check_trigger_is_unique(cmd->convert_src);
+ err |= comedi_check_trigger_is_unique(cmd->stop_src);
/* Step 2b : and mutually compatible */
@@ -208,20 +204,21 @@ static int das16m1_cmd_test(struct comedi_device *dev,
/* Step 3: check if arguments are trivially valid */
- err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
- err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+ err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
if (cmd->convert_src == TRIG_TIMER)
- err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 1000);
+ err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 1000);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+ err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
+ cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT)
- err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
else /* TRIG_NONE */
- err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+ err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
return 3;
@@ -229,12 +226,10 @@ static int das16m1_cmd_test(struct comedi_device *dev,
/* step 4: fix up arguments */
if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
- &devpriv->divisor1,
- &devpriv->divisor2,
- &arg, cmd->flags);
- err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
+ unsigned int arg = cmd->convert_arg;
+
+ comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
+ err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
}
if (err)
@@ -250,25 +245,12 @@ static int das16m1_cmd_test(struct comedi_device *dev,
return 0;
}
-static void das16m1_set_pacer(struct comedi_device *dev)
-{
- struct das16m1_private_struct *devpriv = dev->private;
- unsigned long timer_base = dev->iobase + DAS16M1_8254_SECOND;
-
- i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
- i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
-
- i8254_write(timer_base, 0, 1, devpriv->divisor1);
- i8254_write(timer_base, 0, 2, devpriv->divisor2);
-}
-
static int das16m1_cmd_exec(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct das16m1_private_struct *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- unsigned long timer_base = dev->iobase + DAS16M1_8254_FIRST;
unsigned int byte, i;
/* disable interrupts and internal pacer */
@@ -277,14 +259,21 @@ static int das16m1_cmd_exec(struct comedi_device *dev,
/* set software count */
devpriv->adc_count = 0;
- /* Initialize lower half of hardware counter, used to determine how
+
+ /*
+ * Initialize lower half of hardware counter, used to determine how
* many samples are in fifo. Value doesn't actually load into counter
- * until counter's next clock (the next a/d conversion) */
- i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
- i8254_write(timer_base, 0, 1, 0);
- /* remember current reading of counter so we know when counter has
- * actually been loaded */
- devpriv->initial_hw_count = i8254_read(timer_base, 0, 1);
+ * until counter's next clock (the next a/d conversion).
+ */
+ comedi_8254_set_mode(devpriv->counter, 1, I8254_MODE2 | I8254_BINARY);
+ comedi_8254_write(devpriv->counter, 1, 0);
+
+ /*
+ * Remember current reading of counter so we know when counter has
+ * actually been loaded.
+ */
+ devpriv->initial_hw_count = comedi_8254_read(devpriv->counter, 1);
+
/* setup channel/gain queue */
for (i = 0; i < cmd->chanlist_len; i++) {
outb(i, dev->iobase + DAS16M1_QUEUE_ADDR);
@@ -297,7 +286,8 @@ static int das16m1_cmd_exec(struct comedi_device *dev,
/* enable interrupts and set internal pacer counter mode and counts */
devpriv->control_state &= ~PACER_MASK;
if (cmd->convert_src == TRIG_TIMER) {
- das16m1_set_pacer(dev);
+ comedi_8254_update_divisors(dev->pacer);
+ comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
devpriv->control_state |= INT_PACER;
} else { /* TRIG_EXT */
devpriv->control_state |= EXT_PACER;
@@ -417,8 +407,8 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
async = s->async;
cmd = &async->cmd;
- /* figure out how many samples are in fifo */
- hw_counter = i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+ /* figure out how many samples are in fifo */
+ hw_counter = comedi_8254_read(devpriv->counter, 1);
/* make sure hardware counter reading is not bogus due to initial value
* not having been loaded yet */
if (devpriv->adc_count == 0 && hw_counter == devpriv->initial_hw_count) {
@@ -563,6 +553,16 @@ static int das16m1_attach(struct comedi_device *dev,
dev->irq = it->options[1];
}
+ dev->pacer = comedi_8254_init(dev->iobase + DAS16M1_8254_SECOND,
+ I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
+ if (!dev->pacer)
+ return -ENOMEM;
+
+ devpriv->counter = comedi_8254_init(dev->iobase + DAS16M1_8254_FIRST,
+ 0, I8254_IO8, 0);
+ if (!devpriv->counter)
+ return -ENOMEM;
+
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
return ret;
@@ -609,9 +609,6 @@ static int das16m1_attach(struct comedi_device *dev,
if (ret)
return ret;
- /* disable upper half of hardware conversion counter so it doesn't mess with us */
- outb(TOTAL_CLEAR, dev->iobase + DAS16M1_8254_FIRST_CNTRL);
-
/* initialize digital output lines */
outb(0, dev->iobase + DAS16M1_DIO);
@@ -626,8 +623,11 @@ static void das16m1_detach(struct comedi_device *dev)
{
struct das16m1_private_struct *devpriv = dev->private;
- if (devpriv && devpriv->extra_iobase)
- release_region(devpriv->extra_iobase, DAS16M1_SIZE2);
+ if (devpriv) {
+ if (devpriv->extra_iobase)
+ release_region(devpriv->extra_iobase, DAS16M1_SIZE2);
+ kfree(devpriv->counter);
+ }
comedi_legacy_detach(dev);
}