staging: comedi: adv_pci_dio: Support falling edge triggers
The interrupt support for Advantech PCI-1730 currrently supports only rising edge inputs for the trigger sources. Each of four interrupt sources (each with its own Comedi subdevice) can be set to trigger on either a rising edge or a falling edge. Add support for choosing the edge during set-up of the asynchronous command for the subdevice, using the `CR_INVERT` bit of `scan_begin_arg` to indicate falling edge when set, or rising edge when clear. Also allow the `CR_EDGE` bit to be set, but ignore it. All other bits of `scan_begin_arg` must be zero. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Link: https://lore.kernel.org/r/20210118144359.378730-3-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2e0e629d0f
commit
b4783da2c1
@ -227,6 +227,7 @@ struct pci_dio_dev_private_data {
|
||||
int boardtype;
|
||||
int irq_subd;
|
||||
unsigned short int_ctrl;
|
||||
unsigned short int_rf;
|
||||
};
|
||||
|
||||
struct pci_dio_sd_private_data {
|
||||
@ -313,7 +314,15 @@ static int pci_dio_asy_cmdtest(struct comedi_device *dev,
|
||||
/* Step 3: check if arguments are trivially valid */
|
||||
|
||||
err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
|
||||
err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
|
||||
/*
|
||||
* For scan_begin_arg, the trigger number must be 0 and the only
|
||||
* allowed flags are CR_EDGE and CR_INVERT. CR_EDGE is ignored,
|
||||
* CR_INVERT sets the trigger to falling edge.
|
||||
*/
|
||||
if (cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) {
|
||||
cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
|
||||
err |= -EINVAL;
|
||||
}
|
||||
err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
|
||||
err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
|
||||
cmd->chanlist_len);
|
||||
@ -335,12 +344,18 @@ static int pci_dio_asy_cmd(struct comedi_device *dev,
|
||||
struct pci_dio_dev_private_data *dev_private = dev->private;
|
||||
struct pci_dio_sd_private_data *sd_priv = s->private;
|
||||
const struct dio_boardtype *board = dev->board_ptr;
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
unsigned long cpu_flags;
|
||||
unsigned short int_en;
|
||||
|
||||
int_en = board->sdirq[s->index - dev_private->irq_subd].int_en;
|
||||
|
||||
spin_lock_irqsave(&dev->spinlock, cpu_flags);
|
||||
if (cmd->scan_begin_arg & CR_INVERT)
|
||||
dev_private->int_rf |= int_en; /* falling edge */
|
||||
else
|
||||
dev_private->int_rf &= ~int_en; /* rising edge */
|
||||
outb(dev_private->int_rf, dev->iobase + PCI173X_INT_RF_REG);
|
||||
dev_private->int_ctrl |= int_en; /* enable interrupt source */
|
||||
outb(dev_private->int_ctrl, dev->iobase + PCI173X_INT_EN_REG);
|
||||
spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
|
||||
@ -483,7 +498,8 @@ static int pci_dio_reset(struct comedi_device *dev, unsigned long cardtype)
|
||||
/* Reset all 4 Int Flags */
|
||||
outb(0x0f, dev->iobase + PCI173X_INT_CLR_REG);
|
||||
/* Rising Edge => IRQ . On all 4 Pins */
|
||||
outb(0x00, dev->iobase + PCI173X_INT_RF_REG);
|
||||
dev_private->int_rf = 0x00;
|
||||
outb(dev_private->int_rf, dev->iobase + PCI173X_INT_RF_REG);
|
||||
break;
|
||||
case TYPE_PCI1739:
|
||||
case TYPE_PCI1750:
|
||||
|
Loading…
x
Reference in New Issue
Block a user