X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fstaging%2Fcomedi%2Fdrivers%2Faddi-data%2Fhwdrv_apci3501.c;fp=kernel%2Fdrivers%2Fstaging%2Fcomedi%2Fdrivers%2Faddi-data%2Fhwdrv_apci3501.c;h=1f2f78186d58c1545946e80b3cf0fd371974b9e9;hb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;hp=0000000000000000000000000000000000000000;hpb=98260f3884f4a202f9ca5eabed40b1354c489b29;p=kvmfornfv.git diff --git a/kernel/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/kernel/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c new file mode 100644 index 000000000..1f2f78186 --- /dev/null +++ b/kernel/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -0,0 +1,173 @@ +/* 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; +}