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

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

This driver uses two 8254 timers to generate the pacer clocks. One for analog
input acquisition and one for analog output data conversion. Convert it to use
the comedi_8254 module to provide support for the 8254 timers.

Use the comedi_device 'pacer' member for the 8254 timer used for analog input.
This data is freed automatically by the core during the detach of the driver.

Store the data for the 8254 timer used for analog output in the private data.
This data needs to be freed by the driver when it is detached.
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 6aa37d79
...@@ -918,6 +918,7 @@ config COMEDI_CB_PCIDAS64 ...@@ -918,6 +918,7 @@ config COMEDI_CB_PCIDAS64
config COMEDI_CB_PCIDAS config COMEDI_CB_PCIDAS
tristate "MeasurementComputing PCI-DAS support" tristate "MeasurementComputing PCI-DAS support"
select COMEDI_8254
select COMEDI_8255 select COMEDI_8255
---help--- ---help---
Enable support for ComputerBoards/MeasurementComputing PCI-DAS with Enable support for ComputerBoards/MeasurementComputing PCI-DAS with
......
...@@ -68,7 +68,7 @@ analog triggering on 1602 series ...@@ -68,7 +68,7 @@ analog triggering on 1602 series
#include "../comedidev.h" #include "../comedidev.h"
#include "8253.h" #include "comedi_8254.h"
#include "8255.h" #include "8255.h"
#include "amcc_s5933.h" #include "amcc_s5933.h"
#include "comedi_fc.h" #include "comedi_fc.h"
...@@ -338,14 +338,12 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { ...@@ -338,14 +338,12 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = {
}; };
struct cb_pcidas_private { struct cb_pcidas_private {
struct comedi_8254 *ao_pacer;
/* base addresses */ /* base addresses */
unsigned long s5933_config; unsigned long s5933_config;
unsigned long control_status; unsigned long control_status;
unsigned long adc_fifo; unsigned long adc_fifo;
unsigned long ao_registers; unsigned long ao_registers;
/* divisors of master clock for analog input pacing */
unsigned int divisor1;
unsigned int divisor2;
/* bits to write to registers */ /* bits to write to registers */
unsigned int adc_fifo_bits; unsigned int adc_fifo_bits;
unsigned int s5933_intcsr_bits; unsigned int s5933_intcsr_bits;
...@@ -353,9 +351,6 @@ struct cb_pcidas_private { ...@@ -353,9 +351,6 @@ struct cb_pcidas_private {
/* fifo buffers */ /* fifo buffers */
unsigned short ai_buffer[AI_BUFFER_SIZE]; unsigned short ai_buffer[AI_BUFFER_SIZE];
unsigned short ao_buffer[AO_BUFFER_SIZE]; unsigned short ao_buffer[AO_BUFFER_SIZE];
/* divisors of master clock for analog output pacing */
unsigned int ao_divisor1;
unsigned int ao_divisor2;
unsigned int calibration_source; unsigned int calibration_source;
}; };
...@@ -778,7 +773,6 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, ...@@ -778,7 +773,6 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
struct comedi_cmd *cmd) struct comedi_cmd *cmd)
{ {
const struct cb_pcidas_board *thisboard = dev->board_ptr; const struct cb_pcidas_board *thisboard = dev->board_ptr;
struct cb_pcidas_private *devpriv = dev->private;
int err = 0; int err = 0;
unsigned int arg; unsigned int arg;
...@@ -858,18 +852,12 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, ...@@ -858,18 +852,12 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) { if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg; arg = cmd->scan_begin_arg;
i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
&devpriv->divisor1,
&devpriv->divisor2,
&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg); err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
} }
if (cmd->convert_src == TRIG_TIMER) { if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg; arg = cmd->convert_arg;
i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
&devpriv->divisor1,
&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);
} }
...@@ -886,18 +874,6 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, ...@@ -886,18 +874,6 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
return 0; return 0;
} }
static void cb_pcidas_ai_load_counters(struct comedi_device *dev)
{
struct cb_pcidas_private *devpriv = dev->private;
unsigned long timer_base = dev->iobase + ADC8254;
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 cb_pcidas_ai_cmd(struct comedi_device *dev, static int cb_pcidas_ai_cmd(struct comedi_device *dev,
struct comedi_subdevice *s) struct comedi_subdevice *s)
{ {
...@@ -933,8 +909,11 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, ...@@ -933,8 +909,11 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev,
outw(bits, devpriv->control_status + ADCMUX_CONT); outw(bits, devpriv->control_status + ADCMUX_CONT);
/* load counters */ /* load counters */
if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER) if (cmd->scan_begin_src == TRIG_TIMER ||
cb_pcidas_ai_load_counters(dev); cmd->convert_src == TRIG_TIMER) {
comedi_8254_update_divisors(dev->pacer);
comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
}
/* enable interrupts */ /* enable interrupts */
spin_lock_irqsave(&dev->spinlock, flags); spin_lock_irqsave(&dev->spinlock, flags);
...@@ -1004,7 +983,6 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, ...@@ -1004,7 +983,6 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
const struct cb_pcidas_board *thisboard = dev->board_ptr; const struct cb_pcidas_board *thisboard = dev->board_ptr;
struct cb_pcidas_private *devpriv = dev->private; struct cb_pcidas_private *devpriv = dev->private;
int err = 0; int err = 0;
unsigned int arg;
/* Step 1 : check if triggers are trivially valid */ /* Step 1 : check if triggers are trivially valid */
...@@ -1049,10 +1027,9 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, ...@@ -1049,10 +1027,9 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */ /* step 4: fix up any arguments */
if (cmd->scan_begin_src == TRIG_TIMER) { if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg; unsigned int arg = cmd->scan_begin_arg;
i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
&devpriv->ao_divisor1, comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer,
&devpriv->ao_divisor2,
&arg, cmd->flags); &arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg); err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
} }
...@@ -1139,18 +1116,6 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev, ...@@ -1139,18 +1116,6 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
return 0; return 0;
} }
static void cb_pcidas_ao_load_counters(struct comedi_device *dev)
{
struct cb_pcidas_private *devpriv = dev->private;
unsigned long timer_base = dev->iobase + DAC8254;
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->ao_divisor1);
i8254_write(timer_base, 0, 2, devpriv->ao_divisor2);
}
static int cb_pcidas_ao_cmd(struct comedi_device *dev, static int cb_pcidas_ao_cmd(struct comedi_device *dev,
struct comedi_subdevice *s) struct comedi_subdevice *s)
{ {
...@@ -1180,8 +1145,10 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev, ...@@ -1180,8 +1145,10 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
outw(0, devpriv->ao_registers + DACFIFOCLR); outw(0, devpriv->ao_registers + DACFIFOCLR);
/* load counters */ /* load counters */
if (cmd->scan_begin_src == TRIG_TIMER) if (cmd->scan_begin_src == TRIG_TIMER) {
cb_pcidas_ao_load_counters(dev); comedi_8254_update_divisors(devpriv->ao_pacer);
comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true);
}
/* set pacer source */ /* set pacer source */
spin_lock_irqsave(&dev->spinlock, flags); spin_lock_irqsave(&dev->spinlock, flags);
...@@ -1408,6 +1375,17 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, ...@@ -1408,6 +1375,17 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
} }
dev->irq = pcidev->irq; dev->irq = pcidev->irq;
dev->pacer = comedi_8254_init(dev->iobase + ADC8254,
I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
if (!dev->pacer)
return -ENOMEM;
devpriv->ao_pacer = comedi_8254_init(dev->iobase + DAC8254,
I8254_OSC_BASE_10MHZ,
I8254_IO8, 0);
if (!devpriv->ao_pacer)
return -ENOMEM;
ret = comedi_alloc_subdevices(dev, 7); ret = comedi_alloc_subdevices(dev, 7);
if (ret) if (ret)
return ret; return ret;
...@@ -1550,9 +1528,11 @@ static void cb_pcidas_detach(struct comedi_device *dev) ...@@ -1550,9 +1528,11 @@ static void cb_pcidas_detach(struct comedi_device *dev)
{ {
struct cb_pcidas_private *devpriv = dev->private; struct cb_pcidas_private *devpriv = dev->private;
if (devpriv && devpriv->s5933_config) { if (devpriv) {
if (devpriv->s5933_config)
outl(INTCSR_INBOX_INTR_STATUS, outl(INTCSR_INBOX_INTR_STATUS,
devpriv->s5933_config + AMCC_OP_REG_INTCSR); devpriv->s5933_config + AMCC_OP_REG_INTCSR);
kfree(devpriv->ao_pacer);
} }
comedi_pci_detach(dev); comedi_pci_detach(dev);
} }
......
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