| /* Watchdog Related Defines */ |
| |
| #define ADDIDATA_TIMER 0 |
| #define ADDIDATA_WATCHDOG 2 |
| |
| /* |
| * (*insn_config) for the timer subdevice |
| * |
| * Configures The Timer, Counter or Watchdog |
| * Data Pointer contains configuration parameters as below |
| * data[0] : 0 Configure As Timer |
| * 1 Configure As Counter |
| * 2 Configure As Watchdog |
| * data[1] : 1 Enable Interrupt |
| * 0 Disable Interrupt |
| * data[2] : Time Unit |
| * data[3] : Reload Value |
| */ |
| static int apci3501_config_insn_timer(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
| { |
| struct apci3501_private *devpriv = dev->private; |
| unsigned int ul_Command1 = 0; |
| |
| devpriv->tsk_Current = current; |
| if (data[0] == ADDIDATA_WATCHDOG) { |
| |
| devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG; |
| /* Disable the watchdog */ |
| outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| |
| if (data[1] == 1) { |
| /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */ |
| outl(0x02, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } else { |
| /* disable Timer interrupt */ |
| outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } |
| |
| outl(data[2], dev->iobase + APCI3501_TIMER_TIMEBASE_REG); |
| outl(data[3], dev->iobase + APCI3501_TIMER_RELOAD_REG); |
| |
| /* Set the mode (e2->e0) */ |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG) | 0xFFF819E0UL; |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } |
| |
| else if (data[0] == ADDIDATA_TIMER) { |
| /* First Stop The Timer */ |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| devpriv->b_TimerSelectMode = ADDIDATA_TIMER; |
| if (data[1] == 1) { |
| /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */ |
| outl(0x02, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } else { |
| /* disable Timer interrupt */ |
| outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } |
| |
| outl(data[2], dev->iobase + APCI3501_TIMER_TIMEBASE_REG); |
| outl(data[3], dev->iobase + APCI3501_TIMER_RELOAD_REG); |
| |
| /* mode 2 */ |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = |
| (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL; |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } |
| |
| return insn->n; |
| } |
| |
| /* |
| * (*insn_write) for the timer subdevice |
| * |
| * Start / Stop The Selected Timer , Counter or Watchdog |
| * Data Pointer contains configuration parameters as below |
| * data[0] : 0 Timer |
| * 1 Counter |
| * 2 Watchdog |
| * data[1] : 1 Start |
| * 0 Stop |
| * 2 Trigger |
| */ |
| static int apci3501_write_insn_timer(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
| { |
| struct apci3501_private *devpriv = dev->private; |
| unsigned int ul_Command1 = 0; |
| |
| if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { |
| |
| if (data[1] == 1) { |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; |
| /* Enable the Watchdog */ |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } else if (data[1] == 0) { /* Stop The Watchdog */ |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; |
| outl(0x0, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } else if (data[1] == 2) { |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL; |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } |
| } |
| |
| if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { |
| if (data[1] == 1) { |
| |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; |
| /* Enable the Timer */ |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } else if (data[1] == 0) { |
| /* Stop The Timer */ |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } |
| |
| else if (data[1] == 2) { |
| /* Trigger the Timer */ |
| ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); |
| ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL; |
| outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); |
| } |
| } |
| |
| inl(dev->iobase + APCI3501_TIMER_STATUS_REG); |
| return insn->n; |
| } |
| |
| /* |
| * (*insn_read) for the timer subdevice |
| * |
| * Read The Selected Timer, Counter or Watchdog |
| * Data Pointer contains configuration parameters as below |
| * data[0] : 0 Timer |
| * 1 Counter |
| * 2 Watchdog |
| * data[1] : Timer Counter Watchdog Number |
| */ |
| static int apci3501_read_insn_timer(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
| { |
| struct apci3501_private *devpriv = dev->private; |
| |
| if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { |
| data[0] = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1; |
| data[1] = inl(dev->iobase + APCI3501_TIMER_SYNC_REG); |
| } |
| |
| else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { |
| data[0] = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1; |
| data[1] = inl(dev->iobase + APCI3501_TIMER_SYNC_REG); |
| } |
| |
| else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER) |
| && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) { |
| dev_err(dev->class_dev, "Invalid subdevice.\n"); |
| } |
| return insn->n; |
| } |