From: H Hartley Sweeten Date: Mon, 23 Feb 2015 21:57:36 +0000 (-0700) Subject: staging: comedi: cb_pcidas: convert driver to use the comedi_8254 module X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=96e5624411f99c532175df37c1d8ad8cd908e68a;p=linux-beck.git 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: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 98a62e34b7b6..c15cce4859fe 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -918,6 +918,7 @@ config COMEDI_CB_PCIDAS64 config COMEDI_CB_PCIDAS tristate "MeasurementComputing PCI-DAS support" + select COMEDI_8254 select COMEDI_8255 ---help--- Enable support for ComputerBoards/MeasurementComputing PCI-DAS with diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index dd0c65a5b5a0..b6ef4b47c673 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -68,7 +68,7 @@ analog triggering on 1602 series #include "../comedidev.h" -#include "8253.h" +#include "comedi_8254.h" #include "8255.h" #include "amcc_s5933.h" #include "comedi_fc.h" @@ -338,14 +338,12 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { }; struct cb_pcidas_private { + struct comedi_8254 *ao_pacer; /* base addresses */ unsigned long s5933_config; unsigned long control_status; unsigned long adc_fifo; unsigned long ao_registers; - /* divisors of master clock for analog input pacing */ - unsigned int divisor1; - unsigned int divisor2; /* bits to write to registers */ unsigned int adc_fifo_bits; unsigned int s5933_intcsr_bits; @@ -353,9 +351,6 @@ struct cb_pcidas_private { /* fifo buffers */ unsigned short ai_buffer[AI_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; }; @@ -778,7 +773,6 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { const struct cb_pcidas_board *thisboard = dev->board_ptr; - struct cb_pcidas_private *devpriv = dev->private; int err = 0; unsigned int arg; @@ -858,18 +852,12 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) { arg = cmd->scan_begin_arg; - i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, - &devpriv->divisor1, - &devpriv->divisor2, - &arg, cmd->flags); + comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg); } 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); + comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); } @@ -886,18 +874,6 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 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, struct comedi_subdevice *s) { @@ -933,8 +909,11 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, outw(bits, devpriv->control_status + ADCMUX_CONT); /* load counters */ - if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER) - cb_pcidas_ai_load_counters(dev); + if (cmd->scan_begin_src == TRIG_TIMER || + cmd->convert_src == TRIG_TIMER) { + comedi_8254_update_divisors(dev->pacer); + comedi_8254_pacer_enable(dev->pacer, 1, 2, true); + } /* enable interrupts */ spin_lock_irqsave(&dev->spinlock, flags); @@ -1004,7 +983,6 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, const struct cb_pcidas_board *thisboard = dev->board_ptr; struct cb_pcidas_private *devpriv = dev->private; int err = 0; - unsigned int arg; /* Step 1 : check if triggers are trivially valid */ @@ -1049,11 +1027,10 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, /* step 4: fix up any arguments */ if (cmd->scan_begin_src == TRIG_TIMER) { - arg = cmd->scan_begin_arg; - i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, - &devpriv->ao_divisor1, - &devpriv->ao_divisor2, - &arg, cmd->flags); + unsigned int arg = cmd->scan_begin_arg; + + comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer, + &arg, cmd->flags); 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, 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, struct comedi_subdevice *s) { @@ -1180,8 +1145,10 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev, outw(0, devpriv->ao_registers + DACFIFOCLR); /* load counters */ - if (cmd->scan_begin_src == TRIG_TIMER) - cb_pcidas_ao_load_counters(dev); + if (cmd->scan_begin_src == TRIG_TIMER) { + comedi_8254_update_divisors(devpriv->ao_pacer); + comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true); + } /* set pacer source */ spin_lock_irqsave(&dev->spinlock, flags); @@ -1408,6 +1375,17 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, } 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); if (ret) return ret; @@ -1550,9 +1528,11 @@ static void cb_pcidas_detach(struct comedi_device *dev) { struct cb_pcidas_private *devpriv = dev->private; - if (devpriv && devpriv->s5933_config) { - outl(INTCSR_INBOX_INTR_STATUS, - devpriv->s5933_config + AMCC_OP_REG_INTCSR); + if (devpriv) { + if (devpriv->s5933_config) + outl(INTCSR_INBOX_INTR_STATUS, + devpriv->s5933_config + AMCC_OP_REG_INTCSR); + kfree(devpriv->ao_pacer); } comedi_pci_detach(dev); }