}
};
-/* Private data structure */
-
struct pci9111_private_data {
- unsigned long lcr_io_base; /* Local configuration register base
- * address */
+ unsigned long lcr_io_base;
int stop_counter;
int stop_is_none;
unsigned int chunk_counter;
unsigned int chunk_num_samples;
- int ao_readback; /* Last written analog output data */
+ int ao_readback;
unsigned int div1;
unsigned int div2;
- int is_valid; /* Is device valid */
-
short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
};
-/* ------------------------------------------------------------------ */
-/* PLX9050 SECTION */
-/* ------------------------------------------------------------------ */
-
#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c
#define PLX9050_LINTI1_ENABLE (1 << 0)
outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
}
-/* ------------------------------------------------------------------ */
-/* MISCELLANEOUS SECTION */
-/* ------------------------------------------------------------------ */
-
-/* 8254 timer */
-
static void pci9111_timer_set(struct comedi_device *dev)
{
struct pci9111_private_data *dev_private = dev->private;
outb(0, int_ctrl_reg);
}
-/* ------------------------------------------------------------------ */
-/* HARDWARE TRIGGERED ANALOG INPUT SECTION */
-/* ------------------------------------------------------------------ */
-
-/* Cancel analog input autoscan */
-
static int pci9111_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct pci9111_private_data *dev_private = dev->private;
/* Disable interrupts */
-
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
true, false);
return 0;
}
-/* Test analog input command */
-
-#define pci9111_check_trigger_src(src, flags) do { \
- tmp = src; \
- src &= flags; \
- if (!src || tmp != src) \
- error++; \
- } while (false);
-
-static int
-pci9111_ai_do_cmd_test(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
+static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
struct pci9111_private_data *dev_private = dev->private;
int tmp;
int range, reference;
int i;
- /* Step 1 : check if trigger are trivialy valid */
+ /* Step 1 : check if triggers are trivially valid */
- pci9111_check_trigger_src(cmd->start_src, TRIG_NOW);
- pci9111_check_trigger_src(cmd->scan_begin_src,
- TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
- pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT);
- pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT);
- pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE);
+ error |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+ error |= cfc_check_trigger_src(&cmd->scan_begin_src,
+ TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
+ error |= cfc_check_trigger_src(&cmd->convert_src,
+ TRIG_TIMER | TRIG_EXT);
+ error |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ error |= cfc_check_trigger_src(&cmd->stop_src,
+ TRIG_COUNT | TRIG_NONE);
if (error)
return 1;
- /* step 2 : make sure trigger sources are unique and mutually
- * compatible */
+ /* Step 2a : make sure trigger sources are unique */
- if (cmd->start_src != TRIG_NOW)
- error++;
+ error |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
+ error |= cfc_check_trigger_is_unique(cmd->convert_src);
+ error |= cfc_check_trigger_is_unique(cmd->stop_src);
- if ((cmd->scan_begin_src != TRIG_TIMER) &&
- (cmd->scan_begin_src != TRIG_FOLLOW) &&
- (cmd->scan_begin_src != TRIG_EXT))
- error++;
+ /* Step 2b : and mutually compatible */
- if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT))
- error++;
if ((cmd->convert_src == TRIG_TIMER) &&
!((cmd->scan_begin_src == TRIG_TIMER) ||
(cmd->scan_begin_src == TRIG_FOLLOW)))
- error++;
+ error |= -EINVAL;
if ((cmd->convert_src == TRIG_EXT) &&
!((cmd->scan_begin_src == TRIG_EXT) ||
(cmd->scan_begin_src == TRIG_FOLLOW)))
- error++;
-
-
- if (cmd->scan_end_src != TRIG_COUNT)
- error++;
- if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE))
- error++;
+ error |= -EINVAL;
if (error)
return 2;
i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
&dev_private->div1,
&dev_private->div2,
- &(cmd->convert_arg),
+ &cmd->convert_arg,
cmd->flags & TRIG_ROUND_MASK);
if (tmp != cmd->convert_arg)
error++;
}
-/* Analog input command */
-
static int pci9111_ai_do_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
dev_private->scan_delay = 0;
switch (async_cmd->convert_src) {
case TRIG_TIMER:
- i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
- &dev_private->div1,
- &dev_private->div2,
- &(async_cmd->convert_arg),
- async_cmd->
- flags & TRIG_ROUND_MASK);
-
pci9111_trigger_source_set(dev, software);
pci9111_timer_set(dev);
pci9111_fifo_reset(dev);
array[i] = ((array[i] >> shift) & maxdata) ^ invert;
}
-/* ------------------------------------------------------------------ */
-/* INTERRUPT SECTION */
-/* ------------------------------------------------------------------ */
-
static irqreturn_t pci9111_interrupt(int irq, void *p_device)
{
struct comedi_device *dev = p_device;
return IRQ_HANDLED;
}
-/* ------------------------------------------------------------------ */
-/* INSTANT ANALOG INPUT OUTPUT SECTION */
-/* ------------------------------------------------------------------ */
-
-/* analog instant input */
-
static int pci9111_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
return insn->n;
}
-/* ------------------------------------------------------------------ */
-/* INITIALISATION SECTION */
-/* ------------------------------------------------------------------ */
-
-/* Reset device */
-
static int pci9111_reset(struct comedi_device *dev)
{
struct pci9111_private_data *dev_private = dev->private;
/* Set trigger source to software */
-
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
true, false);
s->range_table = &range_digital;
s->insn_bits = pci9111_do_insn_bits;
- dev_private->is_valid = 1;
-
dev_info(dev->class_dev, "%s attached\n", dev->board_name);
return 0;
static void pci9111_detach(struct comedi_device *dev)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct pci9111_private_data *dev_private = dev->private;
- if (dev_private) {
- if (dev_private->is_valid)
- pci9111_reset(dev);
- }
+ if (dev->iobase)
+ pci9111_reset(dev);
if (dev->irq != 0)
free_irq(dev->irq, dev);
if (pcidev) {
if (dev->iobase)
comedi_pci_disable(pcidev);
- pci_dev_put(pcidev);
}
}