static irqreturn_t pcl711_interrupt(int irq, void *d) { int lo, hi; int data; struct comedi_device *dev = d; struct comedi_subdevice *s = dev->subdevices + 0; if (!dev->attached) { comedi_error(dev, "spurious interrupt"); return IRQ_HANDLED; } hi = inb(dev->iobase + PCL711_AD_HI); lo = inb(dev->iobase + PCL711_AD_LO); outb(0, dev->iobase + PCL711_CLRINTR); data = (hi << 8) | lo; /* FIXME! Nothing else sets ntrig! */ if (!(--devpriv->ntrig)) { if (this_board->is_8112) outb(1, dev->iobase + PCL711_MODE); else outb(0, dev->iobase + PCL711_MODE); s->async->events |= COMEDI_CB_EOA; } comedi_event(dev, s); return IRQ_HANDLED; }
/* +----------------------------------------------------------------------------+ | Function Name : int i_APCI2032_ConfigDigitalOutput | | (struct comedi_device *dev,struct comedi_subdevice *s, | | struct comedi_insn *insn,unsigned int *data) | +----------------------------------------------------------------------------+ | Task : Configures The Digital Output Subdevice. | +----------------------------------------------------------------------------+ | Input Parameters : struct comedi_device *dev : Driver handle | | unsigned int *data : Data Pointer contains | | configuration parameters as below | | | | data[1] : 1 Enable VCC Interrupt | | 0 Disable VCC Interrupt | | data[2] : 1 Enable CC Interrupt | | 0 Disable CC Interrupt | | | +----------------------------------------------------------------------------+ | Output Parameters : -- | +----------------------------------------------------------------------------+ | Return Value : TRUE : No error occur | | : FALSE : Error occur. Return the error | | | +----------------------------------------------------------------------------+ */ int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int ul_Command = 0; devpriv->tsk_Current = current; if ((data[0] != 0) && (data[0] != 1)) { comedi_error(dev, "Not a valid Data !!! ,Data should be 1 or 0\n"); return -EINVAL; } /* if ( (data[0]!=0) && (data[0]!=1) ) */ if (data[0]) { devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; } /* if (data[0]) */ else { devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; } /* else if (data[0]) */ if (data[1] == ADDIDATA_ENABLE) { ul_Command = ul_Command | 0x1; } /* if (data[1] == ADDIDATA_ENABLE) */ else { ul_Command = ul_Command & 0xFFFFFFFE; } /* elseif (data[1] == ADDIDATA_ENABLE) */ if (data[2] == ADDIDATA_ENABLE) { ul_Command = ul_Command | 0x2; } /* if (data[2] == ADDIDATA_ENABLE) */ else { ul_Command = ul_Command & 0xFFFFFFFD; } /* elseif (data[2] == ADDIDATA_ENABLE) */ outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); return insn->n; }
int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int ui_Temp; unsigned int ui_NoOfChannel; ui_NoOfChannel = CR_CHAN(insn->chanspec); if (ui_NoOfChannel > 15) { comedi_error(dev, "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); return -EINVAL; } if ((data[0] != 0) && (data[0] != 1)) { comedi_error(dev, "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n"); return -EINVAL; } ui_Temp = data[0]; *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW); if (ui_Temp == 0) { *data = (*data >> ui_NoOfChannel) & 0x1; }
int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { if ((data[0] != 0) && (data[0] != 1)) { comedi_error(dev, "Not a valid Data !!! ,Data should be 1 or 0\n"); return -EINVAL; } if (data[0]) { devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; } else { devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; } return insn->n; }
static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) { unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); BUG_ON(devpriv->di_mite_chan); devpriv->di_mite_chan = mite_request_channel_in_range(devpriv->mite, devpriv->di_mite_ring, 1, 2); if (devpriv->di_mite_chan == NULL) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); comedi_error(dev, "failed to reserve mite dma channel."); return -EBUSY; } writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) | secondary_DMAChannel_bits(devpriv->di_mite_chan->channel), devpriv->mite->daq_io_addr + DMA_Line_Control_Group1); mmiowb(); spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return 0; }
static irqreturn_t dt2811_interrupt(int irq, void *d) { int lo, hi; int data; struct comedi_device *dev = d; if (!dev->attached) { comedi_error(dev, "spurious interrupt"); return IRQ_HANDLED; } lo = inb(dev->iobase + DT2811_ADDATLO); hi = inb(dev->iobase + DT2811_ADDATHI); data = lo + (hi << 8); if (!(--devpriv->ntrig)) { /* how to turn off acquisition */ s->async->events |= COMEDI_SB_EOA; } comedi_event(dev, s); return IRQ_HANDLED; }
int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int ui_Temp, ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ if (devpriv->b_OutputMemoryStatus) { ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP); } /* if(devpriv->b_OutputMemoryStatus ) */ else { ui_Temp = 0; } /* if(devpriv->b_OutputMemoryStatus ) */ if (data[3] == 0) { if (data[1] == 0) { data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP); } /* if(data[1]==0) */ else { if (data[1] == 1) { switch (ui_NoOfChannel) { case 2: data[0] = (data[0] << (2 * data[2])) | ui_Temp; break; case 4: data[0] = (data[0] << (4 * data[2])) | ui_Temp; break; case 8: data[0] = (data[0] << (8 * data[2])) | ui_Temp; break; case 16: data[0] = (data[0] << (16 * data[2])) | ui_Temp; break; case 31: data[0] = data[0] | ui_Temp; break; default: comedi_error(dev, " chan spec wrong"); return -EINVAL; /* "sorry channel spec wrong " */ } /* switch(ui_NoOfChannels) */ outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP); } /* if(data[1]==1) */ else { printk("\nSpecified channel not supported\n"); } /* else if(data[1]==1) */ } /* elseif(data[1]==0) */ } /* if(data[3]==0) */ else { if (data[3] == 1) { if (data[1] == 0) { data[0] = ~data[0] & 0x1; ui_Temp1 = 1; ui_Temp1 = ui_Temp1 << ui_NoOfChannel; ui_Temp = ui_Temp | ui_Temp1; data[0] = (data[0] << ui_NoOfChannel) ^ 0xffffffff; data[0] = data[0] & ui_Temp; outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP); } /* if(data[1]==0) */ else { if (data[1] == 1) { switch (ui_NoOfChannel) { case 2: data[0] = ~data[0] & 0x3; ui_Temp1 = 3; ui_Temp1 = ui_Temp1 << 2 * data[2]; ui_Temp = ui_Temp | ui_Temp1; data[0] = ((data[0] << (2 * data [2])) ^ 0xffffffff) & ui_Temp; break; case 4: data[0] = ~data[0] & 0xf; ui_Temp1 = 15; ui_Temp1 = ui_Temp1 << 4 * data[2]; ui_Temp = ui_Temp | ui_Temp1; data[0] = ((data[0] << (4 * data [2])) ^ 0xffffffff) & ui_Temp; break; case 8: data[0] = ~data[0] & 0xff; ui_Temp1 = 255; ui_Temp1 = ui_Temp1 << 8 * data[2]; ui_Temp = ui_Temp | ui_Temp1; data[0] = ((data[0] << (8 * data [2])) ^ 0xffffffff) & ui_Temp; break; case 16: data[0] = ~data[0] & 0xffff; ui_Temp1 = 65535; ui_Temp1 = ui_Temp1 << 16 * data[2]; ui_Temp = ui_Temp | ui_Temp1; data[0] = ((data[0] << (16 * data [2])) ^ 0xffffffff) & ui_Temp; break; case 31: break; default: comedi_error(dev, " chan spec wrong"); return -EINVAL; /* "sorry channel spec wrong " */ } /* switch(ui_NoOfChannels) */ outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP); } /* if(data[1]==1) */ else { printk("\nSpecified channel not supported\n"); } /* else if(data[1]==1) */ } /* elseif(data[1]==0) */ } /* if(data[3]==1); */ else { printk("\nSpecified functionality does not exist\n"); return -EINVAL; } /* if else data[3]==1) */ } /* if else data[3]==0) */ return insn->n; }
static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das16_board *board = comedi_board(dev); struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte; unsigned long flags; int range; if (devpriv->dma_chan == 0 || (dev->irq == 0 && devpriv->timer_mode == 0)) { comedi_error(dev, "irq (or use of 'timer mode') dma required to " "execute comedi_cmd"); return -1; } if (cmd->flags & TRIG_RT) { comedi_error(dev, "isa dma transfers cannot be performed with " "TRIG_RT, aborting"); return -1; } devpriv->adc_byte_count = cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t); /* disable conversions for das1600 mode */ if (board->size > 0x400) outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV); /* set scan limits */ byte = CR_CHAN(cmd->chanlist[0]); byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4; outb(byte, dev->iobase + DAS16_MUX); /* set gain (this is also burst rate register but according to * computer boards manual, burst rate does nothing, even on * keithley cards) */ if (board->ai_pg != das16_pg_none) { range = CR_RANGE(cmd->chanlist[0]); outb((das16_gainlists[board->ai_pg])[range], dev->iobase + DAS16_GAIN); } /* set counter mode and counts */ cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg); /* enable counters */ byte = 0; /* Enable burst mode if appropriate. */ if (board->size > 0x400) { if (cmd->convert_src == TRIG_NOW) { outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST); /* set burst length */ byte |= BURST_LEN_BITS(cmd->chanlist_len - 1); } else { outb(0, dev->iobase + DAS1600_BURST); } } outb(byte, dev->iobase + DAS16_PACER); /* set up dma transfer */ flags = claim_dma_lock(); disable_dma(devpriv->dma_chan); /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ clear_dma_ff(devpriv->dma_chan); devpriv->current_buffer = 0; set_dma_addr(devpriv->dma_chan, devpriv->dma_buffer_addr[devpriv->current_buffer]); /* set appropriate size of transfer */ devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd); set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); enable_dma(devpriv->dma_chan); release_dma_lock(flags); /* set up interrupt */ if (devpriv->timer_mode) { devpriv->timer_running = 1; devpriv->timer.expires = jiffies + timer_period(); add_timer(&devpriv->timer); devpriv->control_state &= ~DAS16_INTE; } else { /* clear interrupt bit */ outb(0x00, dev->iobase + DAS16_STATUS); /* enable interrupts */ devpriv->control_state |= DAS16_INTE; } devpriv->control_state |= DMA_ENABLE; devpriv->control_state &= ~PACING_MASK; if (cmd->convert_src == TRIG_EXT) devpriv->control_state |= EXT_PACER; else devpriv->control_state |= INT_PACER; outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); /* Enable conversions if using das1600 mode */ if (board->size > 0x400) outb(0, dev->iobase + DAS1600_CONV); return 0; }
static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { const struct das16_board *board = comedi_board(dev); int err = 0, tmp; int gain, start_chan, i; int mask; /* make sure triggers are valid */ tmp = cmd->start_src; cmd->start_src &= TRIG_NOW; if (!cmd->start_src || tmp != cmd->start_src) err++; tmp = cmd->scan_begin_src; mask = TRIG_FOLLOW; /* if board supports burst mode */ if (board->size > 0x400) mask |= TRIG_TIMER | TRIG_EXT; cmd->scan_begin_src &= mask; if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++; tmp = cmd->convert_src; mask = TRIG_TIMER | TRIG_EXT; /* if board supports burst mode */ if (board->size > 0x400) mask |= TRIG_NOW; cmd->convert_src &= mask; if (!cmd->convert_src || tmp != cmd->convert_src) err++; tmp = cmd->scan_end_src; cmd->scan_end_src &= TRIG_COUNT; if (!cmd->scan_end_src || tmp != cmd->scan_end_src) err++; tmp = cmd->stop_src; cmd->stop_src &= TRIG_COUNT | TRIG_NONE; if (!cmd->stop_src || tmp != cmd->stop_src) err++; if (err) return 1; /** * step 2: make sure trigger sources are unique and * mutually compatible */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT && cmd->scan_begin_src != TRIG_FOLLOW) err++; if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) err++; if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) err++; /* make sure scan_begin_src and convert_src dont conflict */ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) err++; if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) err++; if (err) return 2; /* step 3: make sure arguments are trivially compatible */ if (cmd->start_arg != 0) { cmd->start_arg = 0; err++; } if (cmd->scan_begin_src == TRIG_FOLLOW) { /* internal trigger */ if (cmd->scan_begin_arg != 0) { cmd->scan_begin_arg = 0; err++; } } if (cmd->scan_end_arg != cmd->chanlist_len) { cmd->scan_end_arg = cmd->chanlist_len; err++; } /* check against maximum frequency */ if (cmd->scan_begin_src == TRIG_TIMER) { if (cmd->scan_begin_arg < board->ai_speed * cmd->chanlist_len) { cmd->scan_begin_arg = board->ai_speed * cmd->chanlist_len; err++; } } if (cmd->convert_src == TRIG_TIMER) { if (cmd->convert_arg < board->ai_speed) { cmd->convert_arg = board->ai_speed; err++; } } if (cmd->stop_src == TRIG_NONE) { if (cmd->stop_arg != 0) { cmd->stop_arg = 0; err++; } } if (err) return 3; /* step 4: fix up arguments */ if (cmd->scan_begin_src == TRIG_TIMER) { unsigned int tmp = cmd->scan_begin_arg; /* set divisors, correct timing arguments */ i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1), &(devpriv->divisor2), &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK); err += (tmp != cmd->scan_begin_arg); } if (cmd->convert_src == TRIG_TIMER) { unsigned int tmp = cmd->convert_arg; /* set divisors, correct timing arguments */ i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1), &(devpriv->divisor2), &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK); err += (tmp != cmd->convert_arg); } if (err) return 4; /* check channel/gain list against card's limitations */ if (cmd->chanlist) { gain = CR_RANGE(cmd->chanlist[0]); start_chan = CR_CHAN(cmd->chanlist[0]); for (i = 1; i < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i]) != (start_chan + i) % s->n_chan) { comedi_error(dev, "entries in chanlist must be " "consecutive channels, " "counting upwards\n"); err++; } if (CR_RANGE(cmd->chanlist[i]) != gain) { comedi_error(dev, "entries in chanlist must all " "have the same gain\n"); err++; } } } if (err) return 5; return 0; }
int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int ui_NoOfChannel; unsigned int ui_Temp, ui_Temp1; ui_NoOfChannel = CR_CHAN(insn->chanspec); if (ui_NoOfChannel > 15) { comedi_error(dev, "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); return -EINVAL; } if (devpriv->b_OutputMemoryStatus) { ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP); } else { ui_Temp = 0; } if ((data[1] != 0) && (data[1] != 1)) { comedi_error(dev, "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n"); return -EINVAL; } if (data[3] == 0) { if (data[1] == 0) { data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); } else { if (data[1] == 1) { switch (ui_NoOfChannel) { case 2: data[0] = (data[0] << (2 * data[2])) | ui_Temp; break; case 4: data[0] = (data[0] << (4 * data[2])) | ui_Temp; break; case 8: data[0] = (data[0] << (8 * data[2])) | ui_Temp; break; case 15: data[0] = data[0] | ui_Temp; break; default: comedi_error(dev, " chan spec wrong"); return -EINVAL; } outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); } else { printk("\nSpecified channel not supported\n"); } } } else { if (data[3] == 1) { if (data[1] == 0) { data[0] = ~data[0] & 0x1; ui_Temp1 = 1; ui_Temp1 = ui_Temp1 << ui_NoOfChannel; ui_Temp = ui_Temp | ui_Temp1; data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff; data[0] = data[0] & ui_Temp; outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); } else { if (data[1] == 1) { switch (ui_NoOfChannel) { case 2: data[0] = ~data[0] & 0x3; ui_Temp1 = 3; ui_Temp1 = ui_Temp1 << 2 * data[2]; ui_Temp = ui_Temp | ui_Temp1; data[0] = ((data[0] << (2 * data [2])) ^ 0xffff) & ui_Temp; break; case 4: data[0] = ~data[0] & 0xf; ui_Temp1 = 15; ui_Temp1 = ui_Temp1 << 4 * data[2]; ui_Temp = ui_Temp | ui_Temp1; data[0] = ((data[0] << (4 * data [2])) ^ 0xffff) & ui_Temp; break; case 8: data[0] = ~data[0] & 0xff; ui_Temp1 = 255; ui_Temp1 = ui_Temp1 << 8 * data[2]; ui_Temp = ui_Temp | ui_Temp1; data[0] = ((data[0] << (8 * data [2])) ^ 0xffff) & ui_Temp; break; case 15: break; default: comedi_error(dev, " chan spec wrong"); return -EINVAL; } outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); } else { printk("\nSpecified channel not supported\n"); } } } else { printk("\nSpecified functionality does not exist\n"); return -EINVAL; } } return insn->n; }
/* +----------------------------------------------------------------------------+ | Function Name : int i_APCI2016_WriteDigitalOutput | | (struct comedi_device *dev,struct comedi_subdevice *s, | | struct comedi_insn *insn,unsigned int *data) | +----------------------------------------------------------------------------+ | Task : Writes port value To the selected port | +----------------------------------------------------------------------------+ | Input Parameters : struct comedi_device *dev : Driver handle | | unsigned int ui_NoOfChannels : No Of Channels To Write | | unsigned int *data : Data Pointer to read status | +----------------------------------------------------------------------------+ | Output Parameters : -- | +----------------------------------------------------------------------------+ | Return Value : TRUE : No error occur | | : FALSE : Error occur. Return the error | | | +----------------------------------------------------------------------------+ */ int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int ui_NoOfChannel; unsigned int ui_Temp, ui_Temp1; ui_NoOfChannel = CR_CHAN(insn->chanspec); if (ui_NoOfChannel > 15) { comedi_error(dev, "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); return -EINVAL; } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */ if (devpriv->b_OutputMemoryStatus) { ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP); } /* if (devpriv->b_OutputMemoryStatus ) */ else { ui_Temp = 0; } /* else if (devpriv->b_OutputMemoryStatus ) */ if ((data[1] != 0) && (data[1] != 1)) { comedi_error(dev, "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n"); return -EINVAL; } /* if ((data[1]!=0) && (data[1]!=1)) */ if (data[3] == 0) { if (data[1] == 0) { data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); } /* if (data[1]==0) */ else { if (data[1] == 1) { switch (ui_NoOfChannel) { case 2: data[0] = (data[0] << (2 * data[2])) | ui_Temp; break; case 4: data[0] = (data[0] << (4 * data[2])) | ui_Temp; break; case 8: data[0] = (data[0] << (8 * data[2])) | ui_Temp; break; case 15: data[0] = data[0] | ui_Temp; break; default: comedi_error(dev, " chan spec wrong"); return -EINVAL; /* "sorry channel spec wrong " */ } /* switch(ui_NoOfChannels) */ outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); } /* if (data[1]==1) */ else { printk("\nSpecified channel not supported\n"); } /* else if (data[1]==1) */ } /* else if (data[1]==0) */ } /* if (data[3]==0) */ else { if (data[3] == 1) { if (data[1] == 0) { data[0] = ~data[0] & 0x1; ui_Temp1 = 1; ui_Temp1 = ui_Temp1 << ui_NoOfC