Commit fb5678af authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: pcl812: convert driver to use the comedi_8254 module

This driver uses an 8254 timer to generate the pacer clock used for analog
input data acquisition. Convert it to use the comedi_8254 module to provide
support for the 8254 timer.

Note that the pacer does not have to be stopped when starting a new async
command in pcl812_ai_cmd() or when the card is initialy reset by pcl812_reset().
The counters are all reset when the driver is initially attached and the
counters used by the pacer are stopped when a command is canceled.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 43db062a
...@@ -169,6 +169,7 @@ config COMEDI_PCL730 ...@@ -169,6 +169,7 @@ config COMEDI_PCL730
config COMEDI_PCL812 config COMEDI_PCL812
tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216"
select COMEDI_ISADMA if ISA_DMA_API select COMEDI_ISADMA if ISA_DMA_API
select COMEDI_8254
---help--- ---help---
Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink
ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA, ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA,
......
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
#include "comedi_isadma.h" #include "comedi_isadma.h"
#include "comedi_fc.h" #include "comedi_fc.h"
#include "8253.h" #include "comedi_8254.h"
/* hardware types of the cards */ /* hardware types of the cards */
#define boardPCL812PG 0 /* and ACL-8112PG */ #define boardPCL812PG 0 /* and ACL-8112PG */
...@@ -513,8 +513,6 @@ struct pcl812_private { ...@@ -513,8 +513,6 @@ struct pcl812_private {
unsigned char mode_reg_int; /* there is stored INT number for some card */ unsigned char mode_reg_int; /* there is stored INT number for some card */
unsigned int ai_poll_ptr; /* how many sampes transfer poll */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */
unsigned int max_812_ai_mode0_rangewait; /* setling time for gain */ unsigned int max_812_ai_mode0_rangewait; /* setling time for gain */
unsigned int divisor1;
unsigned int divisor2;
unsigned int use_diff:1; unsigned int use_diff:1;
unsigned int use_mpc508:1; unsigned int use_mpc508:1;
unsigned int use_ext_trg:1; unsigned int use_ext_trg:1;
...@@ -522,21 +520,6 @@ struct pcl812_private { ...@@ -522,21 +520,6 @@ struct pcl812_private {
unsigned int ai_eos:1; unsigned int ai_eos:1;
}; };
static void pcl812_start_pacer(struct comedi_device *dev, bool load_timers)
{
struct pcl812_private *devpriv = dev->private;
unsigned long timer_base = dev->iobase + PCL812_TIMER_BASE;
i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
udelay(1);
if (load_timers) {
i8254_write(timer_base, 0, 2, devpriv->divisor2);
i8254_write(timer_base, 0, 1, devpriv->divisor1);
}
}
static void pcl812_ai_setup_dma(struct comedi_device *dev, static void pcl812_ai_setup_dma(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
unsigned int unread_samples) unsigned int unread_samples)
...@@ -650,7 +633,6 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, ...@@ -650,7 +633,6 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
struct pcl812_private *devpriv = dev->private; struct pcl812_private *devpriv = dev->private;
int err = 0; int err = 0;
unsigned int flags; unsigned int flags;
unsigned int arg;
/* Step 1 : check if triggers are trivially valid */ /* Step 1 : check if triggers are trivially valid */
...@@ -703,11 +685,9 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, ...@@ -703,11 +685,9 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */ /* step 4: fix up any arguments */
if (cmd->convert_src == TRIG_TIMER) { if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg; unsigned int arg = cmd->convert_arg;
i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
&devpriv->divisor1, comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
&devpriv->divisor2,
&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
} }
...@@ -725,8 +705,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -725,8 +705,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned int ctrl = 0; unsigned int ctrl = 0;
unsigned int i; unsigned int i;
pcl812_start_pacer(dev, false);
pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1); pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1);
if (dma) { /* check if we can use DMA transfer */ if (dma) { /* check if we can use DMA transfer */
...@@ -760,7 +738,8 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -760,7 +738,8 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
switch (cmd->convert_src) { switch (cmd->convert_src) {
case TRIG_TIMER: case TRIG_TIMER:
pcl812_start_pacer(dev, true); comedi_8254_update_divisors(dev->pacer);
comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
break; break;
} }
...@@ -918,7 +897,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev, ...@@ -918,7 +897,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev,
outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG, outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
dev->iobase + PCL812_CTRL_REG); dev->iobase + PCL812_CTRL_REG);
pcl812_start_pacer(dev, false); comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
pcl812_ai_clear_eoc(dev); pcl812_ai_clear_eoc(dev);
return 0; return 0;
} }
...@@ -1010,10 +989,6 @@ static void pcl812_reset(struct comedi_device *dev) ...@@ -1010,10 +989,6 @@ static void pcl812_reset(struct comedi_device *dev)
dev->iobase + PCL812_CTRL_REG); dev->iobase + PCL812_CTRL_REG);
pcl812_ai_clear_eoc(dev); pcl812_ai_clear_eoc(dev);
/* stop pacer */
if (board->IRQbits)
pcl812_start_pacer(dev, false);
/* /*
* Invalidate last_ai_chanspec then set analog input to * Invalidate last_ai_chanspec then set analog input to
* known channel/range. * known channel/range.
...@@ -1162,11 +1137,19 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -1162,11 +1137,19 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret) if (ret)
return ret; return ret;
if ((1 << it->options[1]) & board->IRQbits) { if (board->IRQbits) {
ret = request_irq(it->options[1], pcl812_interrupt, 0, dev->pacer = comedi_8254_init(dev->iobase + PCL812_TIMER_BASE,
dev->board_name, dev); I8254_OSC_BASE_2MHZ,
if (ret == 0) I8254_IO8, 0);
dev->irq = it->options[1]; if (!dev->pacer)
return -ENOMEM;
if ((1 << it->options[1]) & board->IRQbits) {
ret = request_irq(it->options[1], pcl812_interrupt, 0,
dev->board_name, dev);
if (ret == 0)
dev->irq = it->options[1];
}
} }
/* we need an IRQ to do DMA on channel 3 or 1 */ /* we need an IRQ to do DMA on channel 3 or 1 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment