H Hartley Sweeten | c919d71 | 2012-10-30 16:57:59 -0700 | [diff] [blame] | 1 | /* Watchdog Related Defines */ |
| 2 | |
H Hartley Sweeten | c919d71 | 2012-10-30 16:57:59 -0700 | [diff] [blame] | 3 | #define ADDIDATA_TIMER 0 |
| 4 | #define ADDIDATA_WATCHDOG 2 |
| 5 | |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 6 | /* |
H Hartley Sweeten | 1ef0cfb | 2013-01-23 12:46:45 -0700 | [diff] [blame] | 7 | * (*insn_config) for the timer subdevice |
| 8 | * |
| 9 | * Configures The Timer, Counter or Watchdog |
| 10 | * Data Pointer contains configuration parameters as below |
| 11 | * data[0] : 0 Configure As Timer |
| 12 | * 1 Configure As Counter |
| 13 | * 2 Configure As Watchdog |
| 14 | * data[1] : 1 Enable Interrupt |
| 15 | * 0 Disable Interrupt |
| 16 | * data[2] : Time Unit |
| 17 | * data[3] : Reload Value |
| 18 | */ |
Fred Akers | 805077b | 2014-03-11 18:19:12 -0400 | [diff] [blame] | 19 | static int apci3501_config_insn_timer(struct comedi_device *dev, |
| 20 | struct comedi_subdevice *s, |
| 21 | struct comedi_insn *insn, |
| 22 | unsigned int *data) |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 23 | { |
H Hartley Sweeten | 015aebe | 2013-01-23 12:43:14 -0700 | [diff] [blame] | 24 | struct apci3501_private *devpriv = dev->private; |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 25 | unsigned int ctrl; |
| 26 | |
| 27 | if (data[0] != ADDIDATA_WATCHDOG && |
| 28 | data[0] != ADDIDATA_TIMER) |
| 29 | return -EINVAL; |
H Hartley Sweeten | 843690b | 2012-10-15 10:15:05 -0700 | [diff] [blame] | 30 | |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 31 | devpriv->tsk_Current = current; |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 32 | |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 33 | devpriv->timer_mode = data[0]; |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 34 | |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 35 | /* first, disable the watchdog or stop the timer */ |
| 36 | if (devpriv->timer_mode == ADDIDATA_WATCHDOG) { |
| 37 | ctrl = 0; |
| 38 | } else { |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 39 | ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG); |
H Hartley Sweeten | 7dc68e3 | 2015-08-12 13:25:48 -0700 | [diff] [blame] | 40 | ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG | |
| 41 | ADDI_TCW_CTRL_ENA); |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 42 | } |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 43 | outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG); |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 44 | |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 45 | /* enable/disable the timer interrupt */ |
H Hartley Sweeten | 7dc68e3 | 2015-08-12 13:25:48 -0700 | [diff] [blame] | 46 | ctrl = (data[1] == 1) ? ADDI_TCW_CTRL_IRQ_ENA : 0; |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 47 | outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG); |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 48 | |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 49 | outl(data[2], devpriv->tcw + ADDI_TCW_TIMEBASE_REG); |
| 50 | outl(data[3], devpriv->tcw + ADDI_TCW_RELOAD_REG); |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 51 | |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 52 | ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG); |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 53 | if (devpriv->timer_mode == ADDIDATA_WATCHDOG) { |
| 54 | /* Set the mode (e2->e0) NOTE: this doesn't look correct */ |
H Hartley Sweeten | 7dc68e3 | 2015-08-12 13:25:48 -0700 | [diff] [blame] | 55 | ctrl |= ~(ADDI_TCW_CTRL_CNT_UP | ADDI_TCW_CTRL_EXT_CLK_MASK | |
| 56 | ADDI_TCW_CTRL_MODE_MASK | ADDI_TCW_CTRL_GATE | |
| 57 | ADDI_TCW_CTRL_TRIG | ADDI_TCW_CTRL_TIMER_ENA | |
| 58 | ADDI_TCW_CTRL_RESET_ENA | ADDI_TCW_CTRL_WARN_ENA | |
| 59 | ADDI_TCW_CTRL_IRQ_ENA | ADDI_TCW_CTRL_ENA); |
H Hartley Sweeten | c85c26b | 2015-08-12 13:25:42 -0700 | [diff] [blame] | 60 | } else { |
H Hartley Sweeten | 9798df7 | 2013-01-23 12:46:22 -0700 | [diff] [blame] | 61 | /* mode 2 */ |
H Hartley Sweeten | 7dc68e3 | 2015-08-12 13:25:48 -0700 | [diff] [blame] | 62 | ctrl &= ~(ADDI_TCW_CTRL_CNTR_ENA | ADDI_TCW_CTRL_MODE_MASK | |
| 63 | ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG | |
| 64 | ADDI_TCW_CTRL_TIMER_ENA | ADDI_TCW_CTRL_RESET_ENA | |
| 65 | ADDI_TCW_CTRL_WARN_ENA | ADDI_TCW_CTRL_ENA); |
| 66 | ctrl |= ADDI_TCW_CTRL_MODE(2) | ADDI_TCW_CTRL_TIMER_ENA; |
H Hartley Sweeten | 9798df7 | 2013-01-23 12:46:22 -0700 | [diff] [blame] | 67 | } |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 68 | outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG); |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 69 | |
| 70 | return insn->n; |
| 71 | } |
| 72 | |
| 73 | /* |
H Hartley Sweeten | 1ef0cfb | 2013-01-23 12:46:45 -0700 | [diff] [blame] | 74 | * (*insn_write) for the timer subdevice |
| 75 | * |
| 76 | * Start / Stop The Selected Timer , Counter or Watchdog |
| 77 | * Data Pointer contains configuration parameters as below |
| 78 | * data[0] : 0 Timer |
| 79 | * 1 Counter |
| 80 | * 2 Watchdog |
| 81 | * data[1] : 1 Start |
| 82 | * 0 Stop |
| 83 | * 2 Trigger |
| 84 | */ |
Fred Akers | 805077b | 2014-03-11 18:19:12 -0400 | [diff] [blame] | 85 | static int apci3501_write_insn_timer(struct comedi_device *dev, |
| 86 | struct comedi_subdevice *s, |
| 87 | struct comedi_insn *insn, |
| 88 | unsigned int *data) |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 89 | { |
H Hartley Sweeten | 015aebe | 2013-01-23 12:43:14 -0700 | [diff] [blame] | 90 | struct apci3501_private *devpriv = dev->private; |
H Hartley Sweeten | 626bb28 | 2015-08-12 13:25:39 -0700 | [diff] [blame] | 91 | unsigned int ctrl; |
H Hartley Sweeten | 843690b | 2012-10-15 10:15:05 -0700 | [diff] [blame] | 92 | |
H Hartley Sweeten | 626bb28 | 2015-08-12 13:25:39 -0700 | [diff] [blame] | 93 | if (devpriv->timer_mode == ADDIDATA_WATCHDOG || |
| 94 | devpriv->timer_mode == ADDIDATA_TIMER) { |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 95 | ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG); |
H Hartley Sweeten | 0d5e030 | 2015-08-12 13:25:49 -0700 | [diff] [blame] | 96 | ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG); |
H Hartley Sweeten | 626bb28 | 2015-08-12 13:25:39 -0700 | [diff] [blame] | 97 | |
| 98 | if (data[1] == 1) { /* enable */ |
H Hartley Sweeten | 0d5e030 | 2015-08-12 13:25:49 -0700 | [diff] [blame] | 99 | ctrl |= ADDI_TCW_CTRL_ENA; |
H Hartley Sweeten | 626bb28 | 2015-08-12 13:25:39 -0700 | [diff] [blame] | 100 | } else if (data[1] == 0) { /* stop */ |
| 101 | if (devpriv->timer_mode == ADDIDATA_WATCHDOG) |
| 102 | ctrl = 0; |
| 103 | else |
H Hartley Sweeten | 0d5e030 | 2015-08-12 13:25:49 -0700 | [diff] [blame] | 104 | ctrl &= ~ADDI_TCW_CTRL_ENA; |
H Hartley Sweeten | 626bb28 | 2015-08-12 13:25:39 -0700 | [diff] [blame] | 105 | } else if (data[1] == 2) { /* trigger */ |
H Hartley Sweeten | 0d5e030 | 2015-08-12 13:25:49 -0700 | [diff] [blame] | 106 | ctrl |= ADDI_TCW_CTRL_TRIG; |
H Hartley Sweeten | 9798df7 | 2013-01-23 12:46:22 -0700 | [diff] [blame] | 107 | } |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 108 | outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG); |
H Hartley Sweeten | 9798df7 | 2013-01-23 12:46:22 -0700 | [diff] [blame] | 109 | } |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 110 | |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 111 | inl(devpriv->tcw + ADDI_TCW_STATUS_REG); |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 112 | return insn->n; |
| 113 | } |
| 114 | |
| 115 | /* |
H Hartley Sweeten | 1ef0cfb | 2013-01-23 12:46:45 -0700 | [diff] [blame] | 116 | * (*insn_read) for the timer subdevice |
| 117 | * |
| 118 | * Read The Selected Timer, Counter or Watchdog |
| 119 | * Data Pointer contains configuration parameters as below |
| 120 | * data[0] : 0 Timer |
| 121 | * 1 Counter |
| 122 | * 2 Watchdog |
| 123 | * data[1] : Timer Counter Watchdog Number |
| 124 | */ |
Fred Akers | 805077b | 2014-03-11 18:19:12 -0400 | [diff] [blame] | 125 | static int apci3501_read_insn_timer(struct comedi_device *dev, |
| 126 | struct comedi_subdevice *s, |
| 127 | struct comedi_insn *insn, |
| 128 | unsigned int *data) |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 129 | { |
H Hartley Sweeten | 015aebe | 2013-01-23 12:43:14 -0700 | [diff] [blame] | 130 | struct apci3501_private *devpriv = dev->private; |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 131 | |
H Hartley Sweeten | f7f909e | 2015-08-12 13:25:40 -0700 | [diff] [blame] | 132 | if (devpriv->timer_mode != ADDIDATA_TIMER && |
| 133 | devpriv->timer_mode != ADDIDATA_WATCHDOG) |
| 134 | return -EINVAL; |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 135 | |
H Hartley Sweeten | 1c38d03 | 2015-08-12 13:25:50 -0700 | [diff] [blame] | 136 | data[0] = inl(devpriv->tcw + ADDI_TCW_STATUS_REG) & |
| 137 | ADDI_TCW_STATUS_OVERFLOW; |
H Hartley Sweeten | cd5d0ae | 2015-08-12 13:25:46 -0700 | [diff] [blame] | 138 | data[1] = inl(devpriv->tcw + ADDI_TCW_VAL_REG); |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 139 | |
ADDI-DATA GmbH | c995fe9 | 2009-02-12 15:14:18 -0800 | [diff] [blame] | 140 | return insn->n; |
| 141 | } |